JNI - 更推荐的另一种调用

280 阅读1分钟

Java 与 C 调用时,其实是在虚拟机里建立了一张映射表,key - value 的形式;

value 时函数的指针;

key 由函数名和参数构成一个唯一的值;


函数的签名:


// [ 表示数组,L 表示 Java 类

([Student;)Lstudent; // 等价 Student[] Xxx(Student[])

([Ljava/lang/String;)[Ljava/lang/Object // 等价 Object[] Xxx(String[] s)

另一种写法,主要是函数注册的方式不同;

// app/src/main/cpp/native-lib.cpp

#include <jni.h>
#include <string>

#define JNI_CLASS_PATH "com/example/superlea/firstjni/MainActivity"

// 定义一个 c++ 函数
extern "C"
JNIEXPORT jstring JNICALL
fun_in_c_register(JNIEnv *env,
                 jobject instance){
    return env->NewStringUTF("this is a test for register!");
}

static JNINativeMethod g_methods[] = {
        // java 函数名 , 返回值类型 , cpp 函数名
        {"_fun_in_java", "()Ljava/lang/String;", (void*)fun_in_c_register},
};

// 加载类的时候调用该函数注册
jint JNI_OnLoad(JavaVM *vm, void *reserved){

    JNIEnv *env = NULL;
    
    vm->GetEnv((void**)&env, JNI_VERSION_1_6); // 拿到一个 JNIEnv 实例

    jclass clazz  = env->FindClass(JNI_CLASS_PATH);
    
    env->RegisterNatives(clazz, g_methods, sizeof(g_methods)/sizeof(g_methods[0]));
    // 语义:注册 clazz 这个 java 类,
    // 其函数映射关系,由 g_methods 决定

    return JNI_VERSION_1_6;
}
// java 层定义函数
public native String _fun_in_java();