Zoeken…


Invoering

JNI (Java Native Interface) is een krachtige tool waarmee Android-ontwikkelaars de NDK kunnen gebruiken en C ++ native code in hun applicaties kunnen gebruiken. Dit onderwerp beschrijft het gebruik van de Java <-> C ++ interface.

Functies in een native bibliotheek oproepen via de JNI-interface

Met de Java Native Interface (JNI) kunt u native functies aanroepen vanuit Java-code en vice versa. Dit voorbeeld laat zien hoe een native functie via JNI kan worden geladen en aangeroepen, deze gaat niet in op toegang tot Java-methoden en velden vanuit native code met behulp van JNI-functies .

Stel dat u een native bibliotheek met de naam libjniexample.so in de map project/libs/<architecture> hebt en dat u een functie uit de JNITest Java-klasse in het pakket com.example.jniexample .

Verklaar in de klasse JNITest de functie als volgt:

public native int testJNIfunction(int a, int b);

Definieer de functie in uw eigen code als volgt:

#include <jni.h>

JNIEXPORT jint JNICALL Java_com_example_jniexample_JNITest_testJNIfunction(JNIEnv *pEnv, jobject thiz, jint a, jint b)
{
    return a + b;
}

Het argument pEnv is een verwijzing naar de JNI-omgeving die u kunt doorgeven aan JNI-functies voor toegang tot methoden en velden van Java-objecten en -klassen. De thiz aanwijzer is een jobject naar het Java-object waarnaar de native methode is aangeroepen (of de klasse als het een statische methode is).

Laad de bibliotheek in uw Java-code in JNITest als volgt:

static{
    System.loadLibrary("jniexample");
}

Let op de lib aan het begin en de .so aan het einde van de bestandsnaam worden weggelaten.

Roep de native functie van Java als volgt aan:

JNITest test = new JNITest();
int c = test.testJNIfunction(3, 4);

Hoe een Java-methode aan te roepen vanuit native code

Met de Java Native Interface (JNI) kunt u Java-functies aanroepen vanuit native code. Hier is een eenvoudig voorbeeld van hoe het te doen:

Java-code:

package com.example.jniexample;
public class JNITest {
    public static int getAnswer(bool) {
        return 42;
    }
}

Native code:

int getTheAnswer()
{
    // Get JNI environment
    JNIEnv *env = JniGetEnv();

    // Find the Java class - provide package ('.' replaced to '/') and class name
    jclass jniTestClass = env->FindClass("com/example/jniexample/JNITest");

    // Find the Java method - provide parameters inside () and return value (see table below for an explanation of how to encode them) 
    jmethodID getAnswerMethod = env->GetStaticMethodID(jniTestClass, "getAnswer", "(Z)I;");

    // Calling the method
    return (int)env->CallStaticObjectMethod(jniTestClass, getAnswerMethod, (jboolean)true);
}

JNI methode handtekening naar Java type:

JNI-handtekening Java-type
Z boolean
B byte
C verkolen
S kort
ik int
J lang
F vlotter
D dubbele
L volledig gekwalificeerde klasse; volledig gekwalificeerde-klasse
[type type[]

Dus voor ons voorbeeld hebben we (Z) I gebruikt - wat betekent dat de functie een Boolean krijgt en een int retourneert.

Hulpprogramma methode in JNI-laag

Deze methode zal helpen om de Java-string van de C ++ string te krijgen.

jstring getJavaStringFromCPPString(JNIEnv *global_env, const char* cstring) {

        jstring nullString = global_env->NewStringUTF(NULL);

        if (!cstring) {
            return nullString;
        }

        jclass strClass = global_env->FindClass("java/lang/String");
        jmethodID ctorID = global_env->GetMethodID(strClass, "<init>",
                "([BLjava/lang/String;)V");
        jstring encoding = global_env->NewStringUTF("UTF-8");

        jbyteArray bytes = global_env->NewByteArray(strlen(cstring));
        global_env->SetByteArrayRegion(bytes, 0, strlen(cstring), (jbyte*) cstring);
        jstring str = (jstring) global_env->NewObject(strClass, ctorID, bytes,
                encoding);

        global_env->DeleteLocalRef(strClass);
        global_env->DeleteLocalRef(encoding);
        global_env->DeleteLocalRef(bytes);

        return str;
    }

Deze methode helpt je om jbyteArray naar char te converteren

char* as_unsigned_char_array(JNIEnv *env, jbyteArray array) {
    jsize length = env->GetArrayLength(array);
    jbyte* buffer = new jbyte[length + 1];

    env->GetByteArrayRegion(array, 0, length, buffer);
    buffer[length] = '\0';

    return (char*) buffer;
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow