前言
前一篇讲述了静态注册,本文讲述动态注册
一、动态注册原理及步骤
原理:利用RegisterNatives方法来注册java方法与JNI函数的意义对应关系
1)利用结构体JNINativeMethod数组记录java方法于函数的对应关系
2)实现JNI_OnLoad方法,在加载动态库后,执行动态注册
3)调用FindClass方法,获取Java对象
4)调用RegisterNatives方法,传入java对象,以及JNINativeMethod数组,以及注册数组完成注册
二、使用步骤
1)编写java代码
//方法对应的是fun1
native void world();
//方法对应的是fun2
native String getName();
2)编写c++代码
void fun1(JNIEnv *env,jobject job){
printf(" 动态注册 fun1");
}
jstring fun2(JNIEnv *env,jobject job){
printf(" 动态注册 fun2");
return (*env)->NewStringUTF(env," 动态注册 fun2 返回值");
}
3)建立方法的映射关系
//Java类的全类名
static const char* mClassName="dynamic/DynamicRegister";
static const JNINativeMethod methods[]={
{"world","()V",(void *)fun1},
{"getName","()Ljava/lang/String;",(void *)fun2},
};
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved){
printf("JNI_OnLoad \n");
JNIEnv* env=NULL;
//获得JNIEnv
int r=(*vm)->GetEnv(vm,(void**)&env,JNI_VERSION_1_4);
if (r!=JNI_OK){
return -1;
}
jclass cls=(*env)->FindClass(env,mClassName);
r=(*env)->RegisterNatives(env,cls,methods,2);
//注册 如果小于0则注册失败
if(r!=JNI_OK){
return -1;
}
printf(" 注册成功\n");
return JNI_VERSION_1_4;
}
4)添加add_library
add_library(dynamicLib SHARED clz_dynamic.c)
5)在java中调用nativa方法
package dynamic;
public class DynamicRegister {
static {
System.load("/Users/xxx/CLionProjects/libso1/cmake-build-debug/libdynamicLib.dylib");
}
//方法对应的是fun1
native void world();
//方法对应的是fun2
native String getName();
public static void main(String[] args) {
DynamicRegister dynamicRegister=new DynamicRegister();
dynamicRegister.world();
System.out.println(dynamicRegister.getName());
}
}
6)测试结果