目录
一、JNI动态注册是什么?
二、JNI动态注册使用步骤
1.新增gMethods数组和JNI_OnLoad函数
2.完整HelloWorld.cpp
3.运行测试
总结
一、JNI动态注册是什么?
静态注册的情况下,java调用的接口和jni层实现的接口有强制的一一对应关系,jni层的接口名必须是java_包名_函数名,但是动态注册情况下,jni的函数名可以自定义,然后通过数组数定义java函数名和jni函数名的对应关系。
二、JNI动态注册使用步骤
1.新增gMethods数组,JNI_OnLoad函数,修改jni接口名
//函数名从Java_HelloWorld_sayhello改为Dynamic_Java_HelloWorld_sayhello
JNIEXPORT void JNICALL Dynamic_Java_HelloWorld_sayhello(JNIEnv *, jobject)
{printf("cpp say hello world\n");
}//gMethods定义了java接口和jni接口的对应关系
static JNINativeMethod gMethods[]=
{{"sayhello","()V",(void*)Dynamic_Java_HelloWorld_sayhello}
};//JNI_OnLoad会在java层动态加载库System.loadLibrary()的时候调用
jint JNI_OnLoad(JavaVM* vm,void* reserved)
{JNIEnv *env=NULL;jint result =-1;if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK){return -1;}//通过反射机制找到HelloWorld类char className[20]={"HelloWorld"};jclass clazz=env->FindClass((const char*)className);//为HelloWorld类定义jni函数调用关系if(env->RegisterNatives(clazz,gMethods,1)<0){return -1;}//默认JNI_VERSION_1_1是不支持JNI_OnLoad的,所以要返回JNI_VERSION_1_4result=JNI_VERSION_1_4;printf("JNI_ONload\n");return result;}
2.完整HelloWorld.cpp
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"#ifdef __cplusplus
extern "C" {
#endif
/** Class: HelloWorld* Method: sayhello* Signature: ()V*/
JNIEXPORT void JNICALL Dynamic_Java_HelloWorld_sayhello(JNIEnv *, jobject)
{printf("cpp say hello world\n");
}static JNINativeMethod gMethods[]=
{{"sayhello","()V",(void*)Dynamic_Java_HelloWorld_sayhello}
};jint JNI_OnLoad(JavaVM* vm,void* reserved)
{JNIEnv *env=NULL;jint result =-1;if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK){return -1;}char className[20]={"HelloWorld"};jclass clazz=env->FindClass((const char*)className);if(env->RegisterNatives(clazz,gMethods,1)<0){return -1;}result=JNI_VERSION_1_4;printf("JNI_ONload\n");return result;}#ifdef __cplusplus
}
#endif
3.运行测试
#编译
gcc HelloWorld.cpp --shared -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC#运行
java HelloWorld
#输出:
#JNI_ONload
#cpp say hello world
#call jni sayhello
总结
动态注册可以自由的定义jni接口。