Cosa fa il metodo registerNatives ()?
-
06-07-2019 - |
Domanda
In java, cosa fa il metodo statico privato registerNatives()
della classe Object?
Soluzione
Le altre risposte sono tecnicamente corrette, ma non molto utili per chi non ha esperienza JNI. : -)
Normalmente, affinché la JVM trovi le tue funzioni native, devono essere nominate in un certo modo. ad esempio, per java.lang.Object.registerNatives
, la funzione C corrispondente è denominata Java_java_lang_Object_registerNatives
. Usando registerNatives
(o meglio, la funzione JNI RegisterNatives
), puoi nominare le tue funzioni C come preferisci.
Ecco il codice C associato (da 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]));
}
(Notare che Object.getClass
non è nell'elenco; verrà comunque chiamato dal " standard " nome di Java_java_lang_Object_getClass
.) Per le funzioni elencate, le funzioni C associate sono come elencato in quella tabella, che è più pratico che scrivere un sacco di funzioni di inoltro.
La registrazione di funzioni native è utile anche se si sta incorporando Java nel proprio programma C e si desidera collegarsi a funzioni all'interno dell'applicazione stessa (anziché all'interno di una libreria condivisa), altrimenti le funzioni utilizzate non sono " & esportato;; poiché questi normalmente non sarebbero stati trovati dal meccanismo di ricerca del metodo standard. La registrazione delle funzioni native può anche essere usata per & Quot; rebind & Quot; un metodo nativo per un'altra funzione C (utile se il tuo programma supporta il caricamento e lo scaricamento dinamico di moduli, per esempio).
Incoraggio tutti a leggere il libro JNI JNI , che parla di questo e molto altro. : -)
Altri suggerimenti
Ciò che potrebbe essere leggermente confuso è che il codice mostrato per java.lang.Object.registerNatives
in una risposta precedente è solo un esempio di come registrare le funzioni native. Questo è il codice che (nell'implementazione di OpenJDK) registra le funzioni native per la classe Object. Per registrare le funzioni native per la propria classe, è necessario chiamare la funzione JNI RegisterNatives
dal codice nativo nella propria libreria. Questo potrebbe sembrare un po 'circolare, ma ci sono un paio di modi per interrompere il ciclo.
-
Segui l'esempio di questa implementazione della classe Object:
a. Nella tua classe Java, dichiara un metodo nativo (preferibilmente statico) chiamato
registerNatives
(o qualsiasi altro nome. Non importa).b. Nel tuo codice nativo, definisci una funzione denominata
Java_<your fully qualified class name>_registerNatives
, che contiene una chiamata alla funzione JNIJNI_OnLoad
.c. Assicurati che nel tuo codice Java, il tuo metodo Java
jint JNI_OnLoad(JavaVM *vm, void *reserved)
sia chiamato prima di qualsiasi chiamata ad altri metodi nativi.
o
-
Usa
System.loadLibrary
a. Nella tua libreria nativa definisci una funzione
env
. Nel corpo di questa funzione, chiama la funzione JNIGetEnv
.b. La VM Java cercherà e chiamerà automaticamente
vm
quando la tua libreria nativa viene caricata da <=>, che dovresti già chiamare, probabilmente in un inizializzatore statico per la tua classe. (Ottieni il puntatore <=> richiesto chiamando la funzione <=> nella tabella a cui punta il puntatore <=>.