Java registerNatives() 方法有什么作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does the registerNatives() method do?
提问by Hubris
In java, what does the private static method registerNatives()
of the Object class do?
java中registerNatives()
Object类的私有静态方法有什么作用?
采纳答案by Chris Jester-Young
The other answers are technically correct, but not very useful for someone with no JNI experience. :-)
其他答案在技术上是正确的,但对于没有 JNI 经验的人来说不是很有用。:-)
Normally, in order for the JVM to find your native functions, they have to be named a certain way. e.g., for java.lang.Object.registerNatives
, the corresponding C function is named Java_java_lang_Object_registerNatives
. By using registerNatives
(or rather, the JNI function RegisterNatives
), you can name your C functions whatever you want.
通常,为了让 JVM 找到您的本机函数,它们必须以某种方式命名。例如,对于java.lang.Object.registerNatives
,相应的 C 函数被命名为Java_java_lang_Object_registerNatives
。通过使用registerNatives
(或者更确切地说,JNI 函数RegisterNatives
),您可以随意命名 C 函数。
Here's the associated C code (from OpenJDK 6):
这是相关的 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]));
}
(Notice that Object.getClass
is not in the list; it will still be called by the "standard" name of Java_java_lang_Object_getClass
.) For the functions listed, the associated C functions are as listed in that table, which is handier than writing a bunch of forwarding functions.
(请注意,Object.getClass
它不在列表中;它仍会以 的“标准”名称调用Java_java_lang_Object_getClass
。)对于列出的函数,关联的 C 函数如该表中所列,这比编写一堆转发函数要方便。
Registering native functions is also useful if you are embedding Java in your C program and want to link to functions within the application itself (as opposed to within a shared library), or the functions being used aren't otherwise "exported", since these would not normally be found by the standard method lookup mechanism. Registering native functions can also be used to "rebind" a native method to another C function (useful if your program supports dynamically loading and unloading modules, for example).
如果您在 C 程序中嵌入 Java 并希望链接到应用程序本身内的函数(而不是共享库内),或者正在使用的函数没有以其他方式“导出”,则注册本机函数也很有用,因为这些通常不会被标准方法查找机制找到。注册本机函数还可用于将本机方法“重新绑定”到另一个 C 函数(例如,如果您的程序支持动态加载和卸载模块,则很有用)。
I encourage everybody to read the JNI book, which talks about this and much more. :-)
我鼓励大家阅读JNI 书籍,其中讨论了这一点以及更多内容。:-)
回答by Eric
What might be slightly confusing is that the code shown for java.lang.Object.registerNatives
in a previous answer is just an exampleof how to register native functions. This is the code that (in the implementation of OpenJDK) registers native functions for class Object. To register native functions for your own class, you must call the JNI function RegisterNatives
from the native code in your own library. This might sound a bit circular, but there are a couple ways to break the loop.
可能有点令人困惑的是,java.lang.Object.registerNatives
先前答案中显示的代码只是如何注册本机函数的示例。这是(在 OpenJDK 的实现中)为类 Object 注册本机函数的代码。要为您自己的类注册本机函数,您必须RegisterNatives
从您自己的库中的本机代码调用 JNI 函数。这听起来可能有点循环,但有几种方法可以打破循环。
Follow the example of this implementation of class Object:
a. In your Java class, declare a native method (preferably static) named
registerNatives
(or any other name. it doesn't matter).b. In your native code, define a function named
Java_<your fully qualified class name>_registerNatives
, which contains a call to the JNI functionRegisterNatives
.c. Make sure that in your Java code, your Java
registerNatives
method is called prior to any calls to other native methods.
按照类 Object 的这个实现的例子:
一种。在您的 Java 类中,声明一个名为
registerNatives
(或任何其他名称。没关系)的本机方法(最好是静态的)。湾 在您的本机代码中,定义一个名为 的函数
Java_<your fully qualified class name>_registerNatives
,其中包含对 JNI 函数的调用RegisterNatives
。C。确保在您的 Java 代码中,您的 Java
registerNatives
方法在对其他本机方法的任何调用之前被调用。
OR
或者
Use
JNI_OnLoad
a. In your native library define a function
jint JNI_OnLoad(JavaVM *vm, void *reserved)
. In the body of this function, call the JNI functionRegisterNatives
.b. The Java VM will automatically look for and call
JNI_OnLoad
when your native library is loaded bySystem.loadLibrary
, which you should already be calling, probably in a static initializer for your class. (You get the requiredenv
pointer by calling theGetEnv
function in the table that thevm
pointer points to.)
用
JNI_OnLoad
一种。在您的本机库中定义一个函数
jint JNI_OnLoad(JavaVM *vm, void *reserved)
。在此函数的主体中,调用 JNI 函数RegisterNatives
。湾
JNI_OnLoad
当您的本机库被加载时,Java VM 将自动查找和调用System.loadLibrary
,您应该已经在调用它,可能在您的类的静态初始化程序中。(您可以env
通过调用指针指向GetEnv
的表中的函数来获取所需的指针vm
。)