質問

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がリストにないことに注意してください; <!> quot; standard <!> quot; Java_java_lang_Object_getClassの名前によって呼び出されます。)リストされた関数の場合、関連するC関数はそのテーブルにリストされているように、多くの転送機能を書くよりも便利です。

ネイティブ関数の登録は、CプログラムにJavaを埋め込み、アプリケーション自体(共有ライブラリ内ではなく)内の関数にリンクしたい場合、または使用されている関数がそうでない場合に便利です<!> quot; exported <!> quot;。これらは通常、標準のメソッド検索メカニズムでは検出されないためです。ネイティブ関数の登録は、<!> quot; rebind <!> quot;にも使用できます。別のC関数へのネイティブメソッド(プログラムがモジュールの動的なロードとアンロードをサポートしている場合などに便利です。

JNI本を読むことをお勧めします。 で、このことなどについて説明しています。 :-)

他のヒント

少し紛らわしいかもしれないのは、前の回答のjava.lang.Object.registerNativesに示されているコードが、ネイティブ関数を登録する方法の単なるであるということです。これは、(OpenJDKの実装で)クラスObjectのネイティブ関数を登録するコードです。独自のクラスのネイティブ関数を登録するには、独自のライブラリのネイティブコードからJNI関数RegisterNativesを呼び出す必要があります。これは少し循環的に聞こえるかもしれませんが、ループを破る方法がいくつかあります。

  1. Objectクラスのこの実装の例に従ってください:

    a。 Javaクラスで、registerNatives(またはその他の名前。重要ではありません)という名前のネイティブメソッド(できれば静的)を宣言します。

    b。ネイティブコードで、JNI関数Java_<your fully qualified class name>_registerNativesへの呼び出しを含むJNI_OnLoadという名前の関数を定義します。

    c。 Javaコードでは、Java jint JNI_OnLoad(JavaVM *vm, void *reserved)メソッドが他のネイティブメソッドの呼び出しの前に呼び出されることを確認してください。

または

  1. System.loadLibrary

    を使用

    a。ネイティブライブラリで関数envを定義します。この関数の本体で、JNI関数GetEnvを呼び出します。

    b。 Java VMは、ネイティブライブラリがvmによってロードされたときに自動的に<=>を探して呼び出します。これは、おそらくクラスの静的初期化子で、既に呼び出しているはずです。 (必要な<=>ポインターを取得するには、<=>ポインターが指すテーブルで<=>関数を呼び出します。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top