このサンプルは、NDK を使用して開発された hello-jni という小さな C / C++ アプリを紹介します。このサンプルは、android-mk ブランチ内の ndk-samples リポジトリの hello-jni ディレクトリにあります。
Android.mk
次の 2 行は、ネイティブ ソースファイルの名前と、ビルドする共有ライブラリの名前を指定しています。ビルドシステムにより lib
プレフィックスと .so
拡張子が付加されるため、ビルドされるライブラリの完全な名前は libhello-jni.so
になります。
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
Android.mk
ファイルの機能と使用方法の詳細については、Android.mk をご覧ください。
Application.mk
次の行は、ビルド対象の CPU とアーキテクチャをビルドシステムに指定しています。この例では、サポートされているすべてのアーキテクチャ向けにビルドを行います。
APP_ABI := all
Application.mk
ファイルとその使用方法の詳細については、Application.mk をご覧ください。
Java サイドの実装
helloJNI.java
ファイルは hellojni/src/com/example/hellojni/
にあります。このプログラムは、ネイティブ サイドから文字列を取得する関数を呼び出し、その文字列を画面に表示します。
ソースコードには、NDK ユーザーにとって特に重要な 3 つの行があります。 ここでは、それらを記述されている順ではなく、使用される順に説明します。
この関数呼び出しは、アプリの起動時に .so
ファイルを読み込みます。
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
このメソッド宣言内の native
キーワードは、関数が共有ライブラリ内にある(つまり、ネイティブ サイドに実装されている)ことを仮想マシンに伝えます。
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Android フレームワークは、前の手順で読み込まれ宣言された関数を呼び出し、文字列を画面に表示します。
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
C サイドの実装
hello-jni.c
ファイルは hello-jni/jni/
にあります。これには Java サイドがリクエストした文字列を返す関数が含まれています。関数の宣言は次のとおりです。
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
この宣言は、Java のソースコード内で宣言されているネイティブ関数に対応しています。戻り値の型である jstring
は、Java Native Interface Specification で定義されているデータ型です。実際は文字列ではなく、Java 文字列へのポインタです。
jstring
の後に関数名を記述します。関数名は、Java の関数名とその関数を含むファイルへのパスに基づいており、次のルールに従って記述します。
- 先頭に
Java_
を付加する。 - ソース ディレクトリの最上位からの相対ファイルパスを記述する。
- スラッシュの代わりにアンダースコアを使用する。
- ファイル拡張子(
.java
)は省略する。 - 最後のアンダースコアの後に関数名を付加する。
上記のルールにより、このサンプルで使用される関数名は Java_com_example_hellojni_HelloJni_stringFromJNI
になります。この名前は、hellojni/src/com/example/hellojni/HelloJni.java
にある stringFromJNI()
という Java 関数を指しています。
JNIEnv*
は VM へのポインタで、jobject
は Java サイドから渡される暗黙的な this
オブジェクトへのポインタです。
次の行は、VM API (*env)
を呼び出して、この API に戻り値(Java サイドの関数がリクエストした文字列)を渡します。
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");