Pregunta

En Java, ¿qué hace el método estático privado registerNatives() de la clase Object?

¿Fue útil?

Solución

Las otras respuestas son técnicamente correctas, pero no muy útiles para alguien sin experiencia en JNI. :-)

Normalmente, para que la JVM encuentre sus funciones nativas, deben nombrarse de cierta manera. por ejemplo, para java.lang.Object.registerNatives, la función C correspondiente se denomina Java_java_lang_Object_registerNatives. Al usar registerNatives (o más bien, la función JNI RegisterNatives), puede nombrar sus funciones C como quiera.

Aquí está el código C asociado (de 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]));
}

(Tenga en cuenta que Object.getClass no está en la lista; seguirá siendo llamado por " estándar " nombre de Java_java_lang_Object_getClass.) Para las funciones enumeradas, las funciones C asociadas son como se enumera en esa tabla, que es más útil que escribir un montón de funciones de reenvío.

El registro de funciones nativas también es útil si está incorporando Java en su programa C y desea vincular funciones dentro de la propia aplicación (a diferencia de dentro de una biblioteca compartida), o si las funciones que se utilizan no son <> quot; exportado " ;, ya que estos normalmente no se encontrarían mediante el mecanismo de búsqueda del método estándar. El registro de funciones nativas también se puede utilizar para & Quot; rebind & Quot; un método nativo para otra función C (útil si su programa admite la carga y descarga dinámica de módulos, por ejemplo).

Animo a todos a leer el libro JNI , que habla de esto y mucho más. :-)

Otros consejos

Lo que puede ser un poco confuso es que el código que se muestra para java.lang.Object.registerNatives en una respuesta anterior es solo un ejemplo de cómo registrar funciones nativas. Este es el código que (en la implementación de OpenJDK) registra funciones nativas para la clase Object. Para registrar funciones nativas para su propia clase, debe llamar a la función JNI RegisterNatives desde el código nativo en su propia biblioteca. Esto puede sonar un poco circular, pero hay un par de formas de romper el ciclo.

  1. Siga el ejemplo de esta implementación de la clase Object:

    a. En su clase Java, declare un método nativo (preferiblemente estático) llamado registerNatives (o cualquier otro nombre. No importa).

    b. En su código nativo, defina una función llamada Java_<your fully qualified class name>_registerNatives, que contiene una llamada a la función JNI JNI_OnLoad.

    c. Asegúrese de que en su código Java, se llame a su método Java jint JNI_OnLoad(JavaVM *vm, void *reserved) antes de cualquier llamada a otros métodos nativos.

O

  1. Usar System.loadLibrary

    a. En su biblioteca nativa, defina una función env. En el cuerpo de esta función, llame a la función JNI GetEnv.

    b. La máquina virtual Java buscará automáticamente y llamará a vm cuando su biblioteca nativa esté cargada por <=>, que ya debería estar llamando, probablemente en un inicializador estático para su clase. (Obtiene el puntero <=> requerido llamando a la función <=> en la tabla a la que apunta el puntero <=>.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top