Was bedeutet die registerNatives () -Methode tun?
-
06-07-2019 - |
Frage
In Java, was macht die private statische Methode registerNatives()
der Object-Klasse tun?
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.
-
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-FunktionRegisterNatives
enthält.c. Stellen Sie sicher, dass in Ihrem Java-Code, Java-
registerNatives
Methode vor alle Anrufe zu anderen nativen Methoden aufgerufen wird.
oder
-
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-FunktionRegisterNatives
.b. Der Java-VM wird automatisch sucht und ruft
JNI_OnLoad
wenn Ihre native Bibliothek vonSystem.loadLibrary
geladen wird, die Sie sollten schon, wahrscheinlich in einem statischen Initialisierer für Ihre Klasse anrufen. (Sie erhalten die erforderlicheenv
Zeiger durch dieGetEnv
Funktion in der Tabelle aufrufen, dass dievm
Zeiger verweist.)