Suche…


Einführung

JNI (Java Native Interface) ist ein leistungsstarkes Tool, mit dem Android-Entwickler das NDK und den nativen C ++ - Code in ihren Anwendungen verwenden können. In diesem Thema wird die Verwendung der Java-C ++ - Schnittstelle beschrieben.

Aufrufen von Funktionen in einer systemeigenen Bibliothek über die JNI-Schnittstelle

Mit der Java Native Interface (JNI) können Sie native Funktionen aus Java-Code aufrufen und umgekehrt. In diesem Beispiel wird gezeigt, wie eine native Funktion über JNI geladen und aufgerufen wird. Sie greift nicht auf Java-Methoden und -Felder aus nativem Code über JNI-Funktionen zu .

Angenommen, Sie verfügen über eine native Bibliothek namens libjniexample.so im Ordner project/libs/<architecture> und möchten eine Funktion aus der JNITest Java-Klasse im Paket com.example.jniexample .

Deklarieren Sie die Funktion in der JNITest-Klasse folgendermaßen:

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

Definieren Sie die Funktion in Ihrem eigenen Code folgendermaßen:

#include <jni.h>

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

Das Argument pEnv ist ein Zeiger auf die JNI-Umgebung, die Sie an JNI-Funktionen übergeben können, um auf Methoden und Felder von Java-Objekten und -Klassen zuzugreifen. Der thiz Zeiger ist eine jobject auf das Java-Objekt, für das die native Methode aufgerufen wurde (oder die Klasse, wenn es sich um eine statische Methode handelt).

Laden Sie die Bibliothek in Ihrem Java-Code in JNITest :

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

Beachten Sie die lib am Anfang und die .so am Ende des Dateinamens werden weggelassen.

Rufen Sie die native Funktion von Java aus folgendermaßen auf:

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

So rufen Sie eine Java-Methode aus nativem Code auf

Mit der Java Native Interface (JNI) können Sie Java-Funktionen aus nativem Code aufrufen. Hier ist ein einfaches Beispiel, wie es geht:

Java-Code:

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

Nativen 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-Methodensignatur für Java-Typ:

JNI-Signatur Java-Typ
Z boolean
B Byte
C verkohlen
S kurz
ich int
J lange
F schweben
D doppelt
L vollqualifizierte Klasse; Vollqualifizierte Klasse
[ Art Art[]

Für unser Beispiel haben wir (Z) I verwendet - was bedeutet, dass die Funktion einen Boolean erhält und ein Int zurückgibt.

Dienstprogrammmethode in der JNI-Schicht

Diese Methode hilft beim Abrufen der Java-Zeichenfolge aus der C ++ - Zeichenfolge.

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

Mit dieser Methode können Sie jbyteArray in char konvertieren

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow