天天看点

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开发静态注册与动态注册(二)前言一、动态注册原理及步骤二、使用步骤

继续阅读