Hub*_*ris 68 c java methods java-native-interface object
在java中,registerNatives()Object类的私有静态方法有什么作用?
Chr*_*ung 105
其他答案在技术上是正确的,但对没有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]));
}
Run Code Online (Sandbox Code Playgroud)
(注意,Object.getClass不是在列表中;它仍然会通过的"标准"的名字叫Java_java_lang_Object_getClass).对于列出的功能,相关的C函数是如在该表,这是比写一堆转发功能更加便利列出.
如果要在您的C程序中嵌入Java并希望链接到应用程序本身内的函数(而不是在共享库中),或者正在使用的函数未以其他方式"导出",则注册本机函数也很有用,因为这些通常不会通过标准方法查找机制找到.注册本机函数也可用于将本机方法"重新绑定"到另一个C函数(例如,如果您的程序支持动态加载和卸载模块,则非常有用).
我鼓励大家阅读JNI书,其中讨论了这个以及更多内容.:-)
小智 8
可能有点令人困惑的是,java.lang.Object.registerNatives前一个答案中显示的代码只是如何注册本机函数的一个示例.这是(在OpenJDK的实现中)为类Object注册本机函数的代码.要为您自己的类注册本机函数,您必须RegisterNatives从您自己的库中的本机代码调用JNI函数.这可能听起来有点圆,但有几种方法可以打破循环.
按照类Object的这个实现的例子:
一个.在您的Java类中,声明一个名为的本机方法(最好是静态的)registerNatives(或任何其他名称.它无关紧要).
湾 在本机代码中,定义一个名为的函数Java_<your fully qualified class name>_registerNatives,该函数包含对JNI函数的调用RegisterNatives.
C.确保在Java代码中,registerNatives在调用其他本机方法之前调用Java 方法.
要么
使用 JNI_OnLoad
一个.在本机库中定义一个函数jint JNI_OnLoad(JavaVM *vm, void *reserved).在此函数的主体中,调用JNI函数RegisterNatives.
湾 Java VM将JNI_OnLoad在您加载本机库时自动查找和调用System.loadLibrary,您应该已经调用了该库,可能是在您的类的静态初始化程序中.(env通过调用指针指向GetEnv的表中的函数,可以获得所需的指针vm.)