Question

En Java, que fait la méthode statique privée registerNatives() de la classe Object?

Était-ce utile?

La solution

Les autres réponses sont techniquement correctes, mais pas très utiles pour quelqu'un qui n'a pas d'expérience JNI. : -)

Normalement, pour que la machine virtuelle Java trouve vos fonctions natives, elles doivent être nommées d'une certaine manière. Par exemple, pour java.lang.Object.registerNatives, la fonction C correspondante est nommée Java_java_lang_Object_registerNatives. En utilisant registerNatives (ou plutôt la fonction JNI RegisterNatives), vous pouvez nommer vos fonctions C comme vous le souhaitez.

Voici le code C associé (à partir d'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]));
}

(Notez que Object.getClass n'est pas dans la liste; il sera toujours appelé par le " standard " nom de Java_java_lang_Object_getClass.) Pour les fonctions répertoriées, les fonctions C associées sont: comme indiqué dans ce tableau, ce qui est plus pratique que d’écrire de nombreuses fonctions de transfert.

L'enregistrement de fonctions natives est également utile si vous incorporez Java dans votre programme C et souhaitez créer un lien vers des fonctions dans l'application elle-même (par opposition à une bibliothèque partagée), ou si les fonctions utilisées ne sont pas autrement " exporté " ;, car ils ne seraient normalement pas trouvés par le mécanisme de recherche de méthode standard. L’enregistrement de fonctions natives peut également être utilisé pour & Quot; relier & Quot; une méthode native à une autre fonction C (utile si votre programme prend en charge le chargement et le déchargement dynamiques de modules, par exemple).

J'encourage tout le monde à lire le livre JNI , qui en parle et bien plus encore. : -)

Autres conseils

Ce qui peut être légèrement déroutant, c'est que le code indiqué pour java.lang.Object.registerNatives dans une réponse précédente est simplement un exemple montrant comment enregistrer des fonctions natives. C'est le code qui (dans l'implémentation d'OpenJDK) enregistre les fonctions natives pour la classe Object. Pour enregistrer des fonctions natives pour votre propre classe, vous devez appeler la fonction JNI RegisterNatives à partir du code natif de votre propre bibliothèque. Cela peut sembler un peu circulaire, mais il existe plusieurs façons de rompre la boucle.

  1. Suivez l'exemple de cette implémentation de la classe Object:

    a. Dans votre classe Java, déclarez une méthode native (de préférence statique) nommée registerNatives (ou tout autre nom. Peu importe).

    b. Dans votre code natif, définissez une fonction nommée Java_<your fully qualified class name>_registerNatives, qui contient un appel à la fonction JNI JNI_OnLoad.

    c. Assurez-vous que dans votre code Java, votre méthode Java jint JNI_OnLoad(JavaVM *vm, void *reserved) est appelée avant tout appel à d'autres méthodes natives.

OU

  1. Utiliser System.loadLibrary

    a. Dans votre bibliothèque native, définissez une fonction env. Dans le corps de cette fonction, appelez la fonction JNI GetEnv.

    b. La machine virtuelle Java recherchera et appellera automatiquement vm lorsque votre bibliothèque native sera chargée par <=>, que vous devriez déjà appeler, probablement dans un initialiseur statique pour votre classe. (Vous obtenez le pointeur <=> requis en appelant la fonction <=> dans la table vers laquelle le pointeur <=> pointe.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top