我们常用javah去生成JNI的头文件,然后去实现自己定义的JNI方法,使用这种方式比较传统,我们可以看到定义的格式甚至连名字都必须按照规范
[cpp] view plaincopy
JNIEXPORT jint JNICALL Java_test_symlink
(JNIEnv *, jobject, jstring, jstring);
完整的结构是Java_classpath_classname_native method name,这样才能当jvm运行的时候根据这个命名规则去找到对应的native的方法。
实际上jvm也同时提供了直接RegisterNative方法手动的注册native方法
下面是一个代码的例子
[cpp] view plaincopy
static JNINativeMethod methods[] = {
{"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
};
(*env)->RegisterNatives(env, cls, methods,
sizeof(methods)/sizeof(JNINativeMethod));
RegisterNative 函数中的参数
RegisterNative(JNIEnv, jclass cls, JNINativeMethod *methods, jint number)
1. methods 是一个二维数组,代表着这个class里的每一个native方法所对应的实现的方法,在前面的例子中表示,一个native 方法retrieveDiretives, 返回值为AssertionStatusDirectives, 所对应的执行的本地方法是JVM_AssertionStatusDirectives
2. 后面的number 代表要指定的native的数量
RegisterNative的实现
RegisterNative 的实现非常简单,就是将class里面native的方法的地址+1指向执行的c代码的函数地址也就是上面的&JVM_AssertionStatusDirectives
[cpp] view plaincopy
address* native_function_addr() const { assert(is_native(), "must be native"); return (address*) (this+1);
阅读(432) | 评论(0) | 转发(0) |