registerNatives() 方法有什么作用?

2022-08-31 12:52:28

在java中,Object类的私有静态方法有什么作用?registerNatives()


答案 1

其他答案在技术上是正确的,但对于没有JNI经验的人来说并不是很有用。:-)

通常,为了使JVM找到您的本机函数,必须以某种方式命名它们。例如,for ,相应的 C 函数被命名为 。通过使用(或者更确切地说,JNI 函数),您可以根据需要命名 C 函数。java.lang.Object.registerNativesJava_java_lang_Object_registerNativesregisterNativesRegisterNatives

以下是相关的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]));
}

(请注意,不在列表中;它仍将由 的“标准”名称调用。对于列出的函数,关联的 C 函数如该表所列,这比编写一堆转发函数更方便。Object.getClassJava_java_lang_Object_getClass

如果要在 C 程序中嵌入 Java 并希望链接到应用程序本身(而不是共享库中)中的函数,或者所使用的函数不会以其他方式“导出”,则注册本机函数也很有用,因为标准方法查找机制通常找不到这些函数。注册本机函数还可用于将本机方法“重新绑定”到另一个C函数(例如,如果您的程序支持动态加载和卸载模块,则很有用)。

我鼓励大家阅读JNI的书,书中谈到了这一点以及更多内容。:-)


答案 2

可能稍微令人困惑的是,前面答案中显示的代码只是如何注册本机函数的一个示例。这是(在 OpenJDK 的实现中)为类 Object 注册本机函数的代码。要为您自己的类注册本机函数,必须从您自己的库中的本机代码中调用 JNI 函数。这听起来可能有点循环,但有几种方法可以打破循环。java.lang.Object.registerNativesRegisterNatives

  1. 请遵循类 Object 的此实现的示例:

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

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

    c.c. 确保在 Java 代码中,在调用其他本机方法之前调用 Java 方法。registerNatives

  1. JNI_OnLoad

    一个。在本机库中定义一个函数。在此函数的主体中,调用 JNI 函数 。jint JNI_OnLoad(JavaVM *vm, void *reserved)RegisterNatives

    b.Java VM 将在加载本机库时自动查找和调用,您应该已经在调用了该库,可能是在类的静态初始值设定项中。(通过调用指针指向的表中的函数,可以获得所需的指针。JNI_OnLoadSystem.loadLibraryenvGetEnvvm