JNI-注册方式

作者: BKQ_SYC | 来源:发表于2019-08-14 09:33 被阅读0次

    Java调用Native方法前,需要注册,将指定的Native方法与so中对应的方法绑定起来。

    注册分为静态注册动态注册

    一、静态注册

    通过JNIEXPORT和JNICALL两个宏定义声明,在虚拟机加载so时发现上面两个宏定义的函数时就会链接到对应的Native方法。

    规则为Java + 包名 + 类名 + 方法名

    例如包名为com.leo.project,类名为RoomActivity
    // Java native method
    public native String showStringJNI();
    // JNI method
    JNIEXPORT jstring JNICALL
    Java_com_leo_project_RoomActivity_showStringJNI(JNIEnv *env,jobject instance)
    
    
    // Java native method
    public native String showString_JNI();
    // JNI method
    JNIEXPORT jstring JNICALL
    Java_com_leo_project_RoomActivity_showString_1JNI(JNIEnv *env,jobject instance)
    

    二、动态注册

    1. java中定义方法
    public native void startServer(String ip, int port)
    
    2.JNI声明
    #include <jni.h>
    extern "C" {
    void native_startServer(JNIEnv *env,jobject obj,
                jstring ip,jint port)
    }
    
    tips: extern "C"的作用是让C++编译器将extern "C"声明的代码当做C语言代码处理,可以避免C++因符号修饰导致代码不能和C语言库中的符号进行链接的问题
    
    3.JNI注册
    a.GetEnv(void** env,jint version)

    参数<env>:env指针对象,通过该方法给env赋值
    参数<version>:JNI版本

    b.FindClass(const char* name)

    参数<name>:为Java定义方法类的路径,例如:com/leo/project/jni/SocketJni

    jclass jc = env->FindClass("com/leo/project/jni/SocketJni")
    
    c.RegisterNatives(jclass clazz,const JNINativeMethod* methods,jint nMethods)

    参数<clazz>:根据Java定义方法类的路径获得的对应jclass类
    参数<methods>:根据方法名、参数、返回值定义的方法集合
    参数<nMethods>:定义的方法数

    d.JNINativeMethod结构体
    typedef struce {
          const char* name;           // 方法名
          const char* signature;      // 参数与返回值表示
          void*      fnPtr;           // 步骤2声明的名字
    } JNINativeMethod;
    
    // 定义需注册的方法集合
    static JNINativeMethod gMethods[] = {
            {"startServer", "(Ljava/lang/String;I)V",(void *) native_startServer}
    }
    
    // 1. JNI_OnLoad方法中根据JavaVM获得JNIEnv
    JNIEnv *env = NULL;
    vm->GetEnv((void **) &env,JNI_VERSION_1_4)
    
    // 2. 根据Java类路径获取jclass
    jclass jc = env->FindClass("com/leo/project/jni/SocketJni")
    
    // 3. 声明方法集合
    static JNINativeMethod gMethods[] = {
        {"startServer","(Ljava/lang/String;I)V",(void *) native_startServer}
    }
    
    // 4. 注册
    env->RegisterNatives(jc,gMethods,NELEM(gMethods))
    

    相关文章

      网友评论

        本文标题:JNI-注册方式

        本文链接:https://www.haomeiwen.com/subject/jnsbjctx.html