JNI-注册方式

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 
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赋值
参数:JNI版本

b.FindClass(const char* 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)

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

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-注册方式)