前言
前一篇講述了靜态注冊,本文講述動态注冊
一、動态注冊原理及步驟
原理:利用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)測試結果