在java中,Object類的私有靜態方法registerNatives()
是做什麼的?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並希望鏈接到應用程序本身內的函數(而不是共享庫內),或者所使用的函數沒有以其他方式「導出」,則註冊本地函數也很有用「,因爲這些通常不會被標準方法查找機制發現。註冊本地函數也可用於將本地方法「重新綁定」到另一個C函數(例如,如果您的程序支持動態加載和卸載模塊,則可用)。
我鼓勵大家閱讀JNI book,這個會談這個以及更多。 :-)
既然你看了源代碼找到它,這很容易猜到是不是?
這是一個本地方法,它被稱爲registerNatives,所以我猜它註冊了基礎平臺的對象。
它也是私人的,所以它可能沒有什麼值得關注的。
你必須是一個封閉的程序員(「一步之遙,沒什麼可看的」),而不習慣人們真正想知道「底層」下發生了什麼的想法。說夠了。 :-P – 2009-06-18 16:42:45
該死的,那是顯而易見的,不是嗎? – aberrant80 2009-06-19 03:41:01
可能有點混淆的是在前面的答案中顯示java.lang.Object.registerNatives
的代碼只是示例如何註冊本地函數。這是(在OpenJDK的實現中)爲類Object註冊本機函數的代碼。要爲您自己的類註冊本機函數,您必須從您自己的庫中的本機代碼調用JNI函數RegisterNatives
。這聽起來有點循環,但有幾種方法可以打破循環。
關注這個實現類對象的例子:
一個。在您的Java類中,聲明名爲
registerNatives
(或任何其他名稱,無關緊要)的本地方法(最好是靜態方法)。b。在您的本機代碼中,定義一個名爲
Java_<your fully qualified class name>_registerNatives
的函數,其中包含對JNI函數RegisterNatives
的調用。c。確保在您的Java代碼中,在調用其他本地方法之前調用Java
registerNatives
方法。
OR
使用
JNI_OnLoad
一個。在你的本地庫中定義一個函數
jint JNI_OnLoad(JavaVM *vm, void *reserved)
。在這個函數的主體中,調用JNI函數RegisterNatives
。b。當您的本機庫被
System.loadLibrary
加載時,Java VM將自動查找並調用JNI_OnLoad
,您應該已經調用了它,可能是在您的類的靜態初始化程序中。 (您可以通過調用函數GetEnv
表中的vm
指針指向獲得所需的env
指針。)
- 1. d3 clipAngle方法到底做了什麼?
- 2. EntityManger.gettransaction.rollback方法實際上做了什麼?
- 3. World()方法在ruby中做了什麼?
- 4. e.preventDefault()方法實際上做了什麼?
- 5. `putForNullKey`方法在hashmap的`put`方法中做了什麼?
- 6. super()方法做什麼?
- 7. jQuery .filter()方法做什麼?
- 8. Android:「setTextFilterEnabled」方法做什麼?
- 9. Container.validate()方法做什麼?
- 10. getiterator()方法做什麼?
- 11. logging.basicConfig做了什麼?
- 12. class_initialize()做了什麼?
- 13. @synchronized()做了什麼?
- 14. 什麼做錯了?
- 15. `tf.strided_slice()`做了什麼?
- 16. L做了什麼?
- 17. 這個operator()語法做了什麼?
- 18. Javascript語法 - 我做錯了什麼?
- 19. Firebase:在onDisconnect方法背後做了什麼? (AS3)
- 20. C#AJAX Web方法 - 我做錯了什麼?
- 21. 構造關鍵字在添加到方法時做了什麼?
- 22. 下面的方法在javascript中做了什麼?
- 23. Vector2.scl方法在LibGdx中做了什麼
- 24. 這個方法對這個列表做了什麼?
- 25. date對象上的getUTC *方法做了什麼?
- 26. ComponentMetaData.FireError方法在SSIS腳本組件中做了什麼
- 27. 這個守護進程方法做了什麼?
- 28. Mask參數在BitmapData類的閾值方法中做了什麼?
- 29. 我做錯了什麼?未定義的方法`COMMENT_CONTENT」
- 30. 有什麼更好的方法做了以下程序(C#3.0)
當然啊,我沒有考慮到的JNI方面...謝謝大家! – Hubris 2009-06-21 12:08:16