Java >> Java tutorial >  >> Tag >> native

Hvordan bruger man JNIs RegisterNatives() metode?

1. Oversigt

I denne korte vejledning tager vi et kig på JNI RegisterNatives() metode, som bruges til at oprette tilknytninger mellem Java- og C++-funktioner.

Først vil vi forklare, hvordan JNI RegisterNatives() virker. Derefter viser vi, hvordan det bruges i java.lang.Object'registerNatives() metode. Til sidst vil vi vise, hvordan man bruger denne funktionalitet i vores egen Java- og C++-kode.

2. JNI RegisterNatives Metode

JVM har to måder at finde og linke indbyggede metoder med Java-kode på. Den første er at kalde en indbygget funktion på en bestemt måde så JVM kan finde det. En anden måde er at bruge JNI RegisterNatives() metode .

Som navnet antyder, RegisterNatives() registrerer native metoder med klassen bestået som et argument. Ved at bruge denne tilgang kan vi navngive vores C++-funktioner, hvad vi vil .

Faktisk java.lang.Object'registerNatives() metoden bruger den anden tilgang. Lad os se et java.lang.Object'registerNatives() metodeimplementering fra OpenJDK 8 i C:

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]));
}

For det første metoden[] array er initialiseret til at gemme tilknytninger mellem Java og C++ funktionsnavne. Derefter ser vi en metode navngivet på en meget specifik måde, Java_java_lang_Object_registerNatives .

Ved at gøre det er JVM'et i stand til at linke det til et indbygget java.lang.Object'registerNatives() metode. Inde i den er metoden[] array bruges i  RegisterNatives() metodekald.

Lad os nu se, hvordan vi kan bruge det i vores egen kode.

3. Brug af RegisterNatives Metode

Lad os starte med Java-klassen:

public class RegisterNativesHelloWorldJNI {

    public native void register();
    public native String sayHello();

    public static void main(String[] args) {
        RegisterNativesHelloWorldJNI helloWorldJNI = new RegisterNativesHelloWorldJNI();
        helloWorldJNI.register();
        helloWorldJNI.sayHello();
    }
}

Vi definerer to native metoder, register() og sayHello(). Førstnævnte vil bruge RegisterNatives() metode til at registrere en brugerdefineret C++ funktion til brug, når den oprindelige sayHello() metode kaldes.

Lad os se C++-implementeringen af ​​Javas register() native metode:

static JNINativeMethod methods[] = {
  {"sayHello", "()Ljava/lang/String;", (void*) &hello },
};


JNIEXPORT void JNICALL Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_register (JNIEnv* env, jobject thsObject) {
    jclass clazz = env->FindClass("com/baeldung/jni/RegisterNativesHelloWorldJNI");

    (env)->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0]));
}

På samme måde som java.lang.Object for eksempel opretter vi først et array til at holde mappings mellem Java og C++ metoder.

Derefter ser vi en funktion kaldet med et fuldt kvalificeret Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_register navn. Desværre skal det kaldes på denne måde, for at JVM kan finde og forbinde det med Java-kode.

Funktionen gør to ting. Først finder den den ønskede Java-klasse. Derefter kalder den RegisterNatives() metode og sender den klassen og mappings-arrayet.

Nu kan vi kalde den anden native metode, sayHello() , hvad end vi ønsker:

JNIEXPORT jstring JNICALL hello (JNIEnv* env, jobject thisObject) {
    std::string hello = "Hello from registered native C++ !!";
    std::cout << hello << std::endl;
    return env->NewStringUTF(hello.c_str());
}

I stedet for det fuldt kvalificerede navn brugte vi et kortere, meningsfuldt navn.

Lad os endelig køre main() metode fra RegisterNativesHelloWorldJNI klasse:

Hello from registered native C++ !!

4. Konklusion

I denne artikel diskuterede vi JNI RegisterNatives() metode. Først forklarede vi, hvad java.lang.Object.registerNatives() metode gør under hætten. Derefter diskuterede vi, hvorfor vi bruger JNI RegisterNatives() metode kan være nyttig. Til sidst viste vi, hvordan man bruger det i vores egen Java- og C++-kode.

Som altid er den komplette kildekode til artiklen tilgængelig på GitHub.


Java tag