Java registerNatives()方法做什么?
在java中,对象类的私有静态方法Java registerNatives()方法做什么?,java,c,object,methods,java-native-interface,Java,C,Object,Methods,Java Native Interface,在java中,对象类的私有静态方法registerNatives()做什么?其他答案在技术上是正确的,但对于没有JNI经验的人来说不是很有用。:-) 通常,为了让JVM找到本机函数,它们必须以某种方式命名。e、 例如,对于java.lang.Object.registerNatives,相应的C函数名为java\u java\u lang\u Object\u registerNatives。通过使用registernations(或者更确切地说,使用JNI函数registernations),
registerNatives()
做什么?其他答案在技术上是正确的,但对于没有JNI经验的人来说不是很有用。:-)
通常,为了让JVM找到本机函数,它们必须以某种方式命名。e、 例如,对于java.lang.Object.registerNatives
,相应的C函数名为java\u java\u lang\u Object\u registerNatives
。通过使用registernations
(或者更确切地说,使用JNI函数registernations
),您可以随意命名C函数
下面是相关的C代码(来自OpenJDK 6):
(请注意,Object.getClass
不在列表中;它仍将被Java\u Java\u lang\u Object\u getClass
的“标准”名称调用)对于列出的函数,相关的C函数如该表中所列,这比编写一组转发函数更方便
如果在C程序中嵌入Java并希望链接到应用程序本身中的函数(与共享库中的函数相反),或者所使用的函数不会以其他方式“导出”,则注册本机函数也很有用,因为标准方法查找机制通常找不到这些函数。注册本机函数还可以用于将本机方法“重新绑定”到另一个C函数(例如,如果您的程序支持动态加载和卸载模块,那么这很有用)
我鼓励每个人都阅读这本书,其中谈到了这一点以及更多内容。:-) 可能有点让人困惑的是,前面答案中显示的
java.lang.Object.RegisterNaties
代码只是如何注册本机函数的一个示例。这是(在OpenJDK实现中)为类对象注册本机函数的代码。要为自己的类注册本机函数,必须从自己库中的本机代码调用JNI函数RegisterNatives
。这听起来可能有点循环,但有几种方法可以打破循环
registerNatives
(或任何其他名称)的本机方法(最好是静态的)
b。在本机代码中,定义一个名为Java\uu registerNatives
的函数,该函数包含对JNI函数registerNatives
的调用
c。确保在Java代码中,在调用其他本机方法之前先调用JavaregisterNatives
方法JNI\u OnLoad
a。在本机库中定义一个函数jint JNI\u OnLoad(JavaVM*vm,void*reserved)
。在此函数体中,调用JNI函数RegisterNatives
b。当您的本机库由System.loadLibrary
加载时,Java VM将自动查找并调用JNI_OnLoad
,您应该已经在调用它,可能是在类的静态初始值设定项中。(通过调用vm
指针指向的表中的GetEnv
函数,可以获得所需的env
指针。)啊,当然,我没有考虑过JNI方面。。。谢谢大家!您编写了完全修饰过的JNI函数名,这让它很混乱:是由VM自动调用的
Java\u Java\u lang\u Object\u registerNatives
,还是c/c++代码必须调用该函数,而不需要所有Javagobblygook@Pavel默认情况下,类fully.qualified.ClassName
中的本机方法methodName
在C-nameJava\u fully\u-qualified\u-ClassName\u-methodName
下搜索(您的C-side代码必须导出)。您可以调用JNIEnv
的RegisterNatives
方法来覆盖此链接。换句话说,如果你不先使用registernations
,“所有的java GobblyBook”[sic]都是必需的。啊,好吧,那么通过只导出一个函数java\u java\u lang\u Object\u registernations
,我实际上可以通过检查cls
的值来链接我所有的JNI内容。我错过了RegisterNaties实际上是java本身的一部分这一部分。所以当某个类即将被使用时,JVM用来链接本机的操作顺序是什么?看起来,如果本地人还没有注册(来自c/c++),JVM会检查所有这些导出的名称,如果它们不存在,那么它会尝试使用Object.registerNatives(或者其他方法?)。顺便说一句,jni book链接已失效。如果您尚未调用注册表项
,并且导出的名称不可用,则在尝试调用该方法时将出现运行时错误Object.registerNatives
是OpenJDK实现java.lang.Object
的内部方法,从其类初始化器调用,其唯一目的是注册仅属于java.lang.Object
的本机方法。如果您正在编写自己的本机库,则由您自己注册库的本机方法(如果您愿意)。
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]));
}