以一个简单的求和函数为例:
public static native int sum(int a, int b);
#include <jni.h>
#include <assert.h>
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
/**
* sum方法的具体实现
*/
JNIEXPORT jint JNICALL native_sum(JNIEnv *jniEnv, jclass jclz, jint a, jint b) {
return a + b;
}
/**
*把所有native方法添加至此处
*/
static const JNINativeMethod gMethods[] = {
{
//参数依次为:java中的函数;函数签名;C中对应的函数
"sum", "(II)I", (void *) native_sum
}
};
static int registerNatives(JNIEnv *env) {
jclass class;
class = (*env)->FindClass(env,
//声明sum方法所在的位置 "com/example/chauncey/ndk_lsn9_2_dynamic_registration/Utils");
if (class == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, class, gMethods, NELEM(gMethods)) < 0) {
return JNI_FALSE;
};
return JNI_TRUE;
}
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return result;
}
assert(env != NULL);
registerNatives(env);
//必须返回JNI_VERSION
return JNI_VERSION_1_4;
}
静态注册:
- 每个class都需要使用javah生成一个头文件(也可以手写,最方便的方法是通过javah生成),并且生成的名字很长书写不便(Java_xxx_sum);
- 初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率;
动态注册:
- 使用一种数据结构JNINativeMethod来记录Java native函数和JNI函数的对应关系;
- JNI方法名可以自定义,书写更加方便;
- 移植方便(一个java文件中有多个native方法,java文件的包名更换后,JNI方法也需要变更)