天天看點

JNI開發靜态注冊與動态注冊(二)前言一、動态注冊原理及步驟二、使用步驟

前言

前一篇講述了靜态注冊,本文講述動态注冊

一、動态注冊原理及步驟

原理:利用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)測試結果

JNI開發靜态注冊與動态注冊(二)前言一、動态注冊原理及步驟二、使用步驟

繼續閱讀