Frage

In Java, was macht die private statische Methode registerNatives() der Object-Klasse tun?

War es hilfreich?

Lösung

Die anderen Antworten sind technisch korrekt, aber nicht sehr nützlich für jemanden ohne JNI Erfahrung. : -)

Normalerweise für die JVM, um Ihre nativen Funktionen zu finden, müssen sie eine bestimmte Art und Weise benannt werden. z.B. für java.lang.Object.registerNatives, wird die entsprechende C Funktion Java_java_lang_Object_registerNatives benannt. Durch die Verwendung von registerNatives (oder besser gesagt, die JNI-Funktion RegisterNatives), können Sie Ihre C-Funktionen nennen, was Sie wollen.

Hier ist der zugehörige C-Code (von 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]));
}

(Beachten Sie, dass Object.getClass ist nicht in der Liste, es wird immer noch von den „Standard“ Namen Java_java_lang_Object_getClass genannt werden.) Für die Funktionen aufgelistet, werden die zugehörigen C-Funktionen wie in der Tabelle aufgeführt, das ist handlicher als ein Schreiben Bündel von Weiterleitungsfunktionen.

Speichern von nativen Funktionen ist auch nützlich, wenn Sie Java in Ihrem C-Programm einbetten und möchte Funktionen innerhalb der Anwendung selbst (im Gegensatz zu innerhalb einer Shared Library) zu verbinden, oder die Funktionen verwendet werden, nicht anders „exportiert“ , da diese normalerweise nicht durch das Standardverfahren Lookup-Mechanismus gefunden werden würde. Registrieren von nativen Funktionen können auch eine native Methode auf einem anderen C-Funktion (nützlich, wenn Ihr Programm unterstützt dynamischen Laden und Entladen von Modulen, zum Beispiel).

auf „rebind“ verwendet werden,

Ich ermutige alle das JNI Buch zu lesen , die spricht über dies und vieles mehr. : -)

Andere Tipps

Was könnte etwas verwirrend ist, dass der Code für java.lang.Object.registerNatives in einer früheren Antwort gezeigt ist nur ein Beispiel , wie native Funktionen zu registrieren. Dies ist der Code, der (bei der Umsetzung von OpenJDK) registriert native Funktionen für Object-Klasse. Um native Funktionen für die eigene Klasse zu registrieren, müssen Sie die JNI-Funktion RegisterNatives aus dem nativen Code in die eigene Bibliothek aufrufen. Dies könnte ein wenig Kreis klingen, aber es gibt ein paar Möglichkeiten, um die Schleife zu brechen.

  1. Am Beispiel dieser Implementierung von Object-Klasse wie folgt vor:

    a. In Ihrer Java-Klasse deklariert eine native Methode (vorzugsweise statisch) genannt registerNatives (oder einen anderen Namen. Es spielt keine Rolle).

    b. In Ihrem nativen Code, definieren eine Funktion namens Java_<your fully qualified class name>_registerNatives, die einen Aufruf an die JNI-Funktion RegisterNatives enthält.

    c. Stellen Sie sicher, dass in Ihrem Java-Code, Java-registerNatives Methode vor alle Anrufe zu anderen nativen Methoden aufgerufen wird.

oder

  1. Mit JNI_OnLoad

    a. In Ihrer Mutter Bibliothek definiert eine Funktion jint JNI_OnLoad(JavaVM *vm, void *reserved). Im Körper dieser Funktion rufen Sie die JNI-Funktion RegisterNatives.

    b. Der Java-VM wird automatisch sucht und ruft JNI_OnLoad wenn Ihre native Bibliothek von System.loadLibrary geladen wird, die Sie sollten schon, wahrscheinlich in einem statischen Initialisierer für Ihre Klasse anrufen. (Sie erhalten die erforderliche env Zeiger durch die GetEnv Funktion in der Tabelle aufrufen, dass die vm Zeiger verweist.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top