在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。这可能听起来有点圆,但有几种方法可以打破循环。

  1. 按照类Object的实现示例:

    一个。在您的Java类中,声明一个名为registerNatives的本机方法(最好是静态的)(或任何其他名称。这没关系)。

    湾在本机代码中,定义一个名为Java_<your fully qualified class name>_registerNatives的函数,该函数包含对JNI函数JNI_OnLoad的调用。

    ℃。确保在Java代码中,在调用其他本机方法之前调用Java jint JNI_OnLoad(JavaVM *vm, void *reserved)方法。

  2. OR

    1. 使用System.loadLibrary

      一个。在本机库中定义一个函数env。在此函数的主体中,调用JNI函数GetEnv

      湾当您的本机库由vm加载时,Java VM将自动查找并调用<=>,您应该已经在调用它,可能是在您的类的静态初始化程序中。 (通过调用<=>指针指向的表中的<=>函数,可以获得所需的<=>指针。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top