registerNatives()方法有什么作用?
-
06-07-2019 - |
题
在java中,Object类的私有静态方法registerNatives()
做什么?
解决方案
其他答案在技术上是正确的,但对没有JNI经验的人来说不是很有用。 : - )
通常,为了让JVM找到您的本机函数,必须以某种方式命名它们。例如,对于java.lang.Object.registerNatives
,相应的C函数名为Java_java_lang_Object_registerNatives
。通过使用registerNatives
(或者更确切地说,JNI函数RegisterNatives
),您可以根据需要为C函数命名。
这是相关的C代码(来自OpenJDK 6):
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
(请注意Object.getClass
不在列表中;它仍将由<!>“标准<!>”名称Java_java_lang_Object_getClass
调用。)对于列出的函数,关联的C函数是如该表中所列,比编写一堆转发函数更容易。
如果要在C程序中嵌入Java并希望链接到应用程序本身内的函数(而不是在共享库中),或者正在使用的函数不是<!>,则注册本机函数也很有用。 quot; export <!> quot;,因为标准方法查找机制通常不会找到它们。注册本机函数也可用于<!> quot; rebind <!> quot;另一个C函数的本机方法(例如,如果您的程序支持动态加载和卸载模块,则非常有用)。
我鼓励大家阅读 JNI书籍,谈论这个以及更多。 : - )
其他提示
可能有点令人困惑的是,前一个答案中为java.lang.Object.registerNatives
显示的代码只是一个如何注册本机函数的示例。这是(在OpenJDK的实现中)为类Object注册本机函数的代码。要为您自己的类注册本机函数,必须从您自己库中的本机代码调用JNI函数RegisterNatives
。这可能听起来有点圆,但有几种方法可以打破循环。
-
按照类Object的实现示例:
一个。在您的Java类中,声明一个名为
registerNatives
的本机方法(最好是静态的)(或任何其他名称。这没关系)。湾在本机代码中,定义一个名为
Java_<your fully qualified class name>_registerNatives
的函数,该函数包含对JNI函数JNI_OnLoad
的调用。℃。确保在Java代码中,在调用其他本机方法之前调用Java
jint JNI_OnLoad(JavaVM *vm, void *reserved)
方法。
醇>
-
使用
System.loadLibrary
一个。在本机库中定义一个函数
env
。在此函数的主体中,调用JNI函数GetEnv
。湾当您的本机库由
vm
加载时,Java VM将自动查找并调用<=>,您应该已经在调用它,可能是在您的类的静态初始化程序中。 (通过调用<=>指针指向的表中的<=>函数,可以获得所需的<=>指针。)
醇>
OR