Beispiel: hello-jni

In diesem Beispiel wird hello-jni beschrieben, eine minimale C/C++-Anwendung, die mit dem NDK erstellt wurde. Dieses Beispiel befindet sich im Verzeichnis hello-jni des ndk-samples-Repositorys im android-mk-Branch.

Android.mk

Die folgenden beiden Zeilen enthalten den Namen der nativen Quelldatei sowie den Namen der zu erstellenden freigegebenen Bibliothek. Der vollständige Name der erstellten Bibliothek ist libhello-jni.so, sobald das Build-System das Präfix lib und die Erweiterung .so hinzugefügt hat.

LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE    := hello-jni

Weitere Informationen zur Funktion und Verwendung der Datei Android.mk finden Sie unter Android.mk.

Application.mk

Diese Zeile gibt dem Build-System die CPU und die Architektur an, für die es erstellt werden soll. In diesem Beispiel führt das Build-System einen Build für alle unterstützten Architekturen aus.

APP_ABI := all

Weitere Informationen zur Datei Application.mk und ihrer Verwendung finden Sie unter Application.mk.

Java-seitige Implementierung

Die Datei helloJNI.java befindet sich in hellojni/src/com/example/hellojni/. Es ruft eine Funktion auf, um einen String von der nativen Seite abzurufen, und zeigt ihn dann auf dem Bildschirm an.

Der Quellcode enthält drei Zeilen, die für NDK-Nutzer von besonderem Interesse sind. Sie werden hier in der Reihenfolge ihrer Verwendung und nicht in der Zeilenreihenfolge aufgeführt.

Durch diesen Funktionsaufruf wird die Datei .so beim Start der Anwendung geladen.

Kotlin

System.loadLibrary("hello-jni")

Java

System.loadLibrary("hello-jni");

Das Keyword native in dieser Methodendeklaration teilt der virtuellen Maschine mit, dass sich die Funktion in der freigegebenen Bibliothek befindet (d. h. nativ implementiert ist).

Kotlin

external fun stringFromJNI(): String

Java

public native String stringFromJNI();

Das Android-Framework ruft die Funktion auf, die in den vorherigen Schritten geladen und deklariert wurde, und zeigt den String auf dem Bildschirm an.

Kotlin

tv.text = stringFromJNI()

Java

tv.setText( stringFromJNI() );

C-seitige Implementierung

Die Datei hello-jni.c befindet sich unter hello-jni/jni/. Sie enthält eine Funktion, die einen String zurückgibt, den von der Java-Seite angefordert wurde. Die Funktionsdeklaration sieht so aus:

JNIEXPORT jstring JNICALL
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )

Diese Deklaration entspricht der nativen Funktion, die im Java-Quellcode deklariert wurde. Der Rückgabetyp jstring ist ein Datentyp, der in der Java Native Interface Specification definiert ist. Es ist eigentlich kein String, sondern ein Verweis auf einen Java-String.

Nach jstring folgt der Funktionsname, der auf dem Namen der Java-Funktion und dem Pfad zur Datei basiert, die sie enthält. Erstellen Sie sie gemäß den folgenden Regeln:

  • Stellen Sie Java_ voran.
  • Geben Sie den Dateipfad relativ zum Quellverzeichnis der obersten Ebene an.
  • Verwenden Sie Unterstriche anstelle von Schrägstrichen.
  • Lassen Sie die Dateiendung .java weg.
  • Fügen Sie nach dem letzten Unterstrich den Funktionsnamen an.

Gemäß diesen Regeln wird in diesem Beispiel der Funktionsname Java_com_example_hellojni_HelloJni_stringFromJNI verwendet. Dieser Name bezieht sich auf eine Java-Funktion namens stringFromJNI(), die sich in hellojni/src/com/example/hellojni/HelloJni.java befindet.

JNIEnv* ist der Verweis auf die VM und jobject ist ein Verweis auf das implizite this-Objekt, das von der Java-Seite übergeben wird.

In der folgenden Zeile wird die VM-API (*env) aufgerufen und ihr ein Rückgabewert übergeben: der String, der von der Funktion auf Java-Seite angefordert wurde.

return (*env)->NewStringUTF(env, "Hello from JNI !
Compiled with ABI " ABI ".");