AndroidStudioでJNIサンプルのhello-jniをC++で呼び出すプロジェクトを作る
Android もほとんど触ったことがないわけですが、NDK を使わないといけなくなってしまったので勉強中です。
C++ で書いてある自前ライブラリを使いたいので、C++ のライブラリをネイティブプラグイン化しないといけません。
NDK は大半の話が C 言語前提で書かれているので結構困ります。
手始めに、NDKに同梱されているサンプルプロジェクトを C++ に書き換えて、JNI のサンプルプロジェクトを作ってみました。
IDE と NDK は、以下のものを使用しました。
IDE: Android Studio 1.3 beta
NDK: android-ndk-r10e
まずは C 言語のまま、サンプルプロジェクトを JNI で呼び出してみます。
1. Android Studio で新規プロジェクトを作成する
[New Project]
Application name: HelloJniTest
Company domein: example.com
Package name: com.example.hellojnitest
[Target Android Devices]
“Phone and Tablet" にチェック
Minimum SDK: API 21: Android 5.0 (Lolipop)
[Add an activity mobile]
Blank Activity を選択
[Customize the Activity]
デフォルトのまま
2. hello-jni をプロジェクトに追加する
HelloJniTest/app/src/main 直下に android-ndk-r10e/samples/hello-jni 直下にある “jni" フォルダをコピーします。
3. hello-jni のネイティブプラグインを生成する
ターミナルを起動して、HelloJniTest/app/src/main/jni へ移動します。
ターミナルから ndk-build を実行します。
HelloJniTest/app/src/main/libs にビルドされた .so ファイルが追加されます。
4. libs フォルダを HelloJniTest のビルド時に参照するようにする
HelloJniTest/app 直下にある build.gradle を以下のように変更します。
具体的には、sourceSets の部分を追加します。
上の行を入れると、NDK の自動ビルドが行われなくなります。
下の行はビルド時に参照しに行くフォルダを設定しています。
何も書かないと “jniLibs" の方だけ参照されますが、ndk-build で出力されるファイルは “libs" に出力されるので、参照先を追加している感じです。
“jniLibs" のパスも書いていますが、特に読み込むファイルがなければ、書かなくてもいいです。
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "23.0.0 rc2" defaultConfig { applicationId "com.example.hellojnitest" minSdkVersion 21 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { jni.srcDirs = [] jniLibs.srcDirs = ["src/main/jniLibs", "src/main/libs"] } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) }
5. アプリ上に表示する部分を作る
android-ndk-r10e/samples/hello-jni/src/com/example/hellojni/HelloJni.java
のソースコードから、import の部分と、class HelloJni の中身だけを、
HelloJniTest/app/src/main/java/com/example/hellojnitest/MainActivity.java のソースコードに上書きします。
6. Android Studio でビルドする
エラーが出ないことを強く祈ります。
7. シミュレータで起動してみる
シミュレータには、"Nexus 5 API 22 x86″ を使用しました。
起動して、「Hello from JNI ! Compiled with ABI x86.」と表示されれば OK です。
というわけでサンプルプロジェクトは無事に起動しました。
今度はサンプルプロジェクトのソースコードを C++ に変更してみます。
1. Android.mk の編集
LOCAL_SRC_FILES := hello-jni.c
の部分を、
LOCAL_SRC_FILES := hello-jni.cpp
に変更します。
2. hello-jni.cpp を追加する
hello-jni.c のファイル名を hello-jni.cpp に変更します。
3. hello-jni.cpp を編集する
関数部分を以下のように書き換えます。
extern "C" { jstring Java_com_example_hellojnitest_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz); } jstring Java_com_example_hellojnitest_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz) { // #ifdef 群は,そのまま. return env->NewStringUTF("Hello from JNI C++ ! Compiled with ABI " ABI "."); }
問題なのは、C と C++ では JNIEnv の持っている関数が違うことです。
ここでしばらく悩みました。次からはさっさとソースコードを確認するようにします。
// C:
return (*env)->NewStringUTF(env, “Hello from JNI ! Compiled with ABI " ABI “.");
// C++:
return env->NewStringUTF(“Hello from JNI C++ ! Compiled with ABI " ABI “.");
4. hello-jni のネイティブプラグインを生成する
C の時と同様に、"HelloJniTest/app/src/main/jni" で ndk-build を行います。
5. Android Studio でビルドする
ビルドが通ったら、シミュレータで起動します。
6. シミュレータで起動してみる
使用するシミュレータは、先ほどと同様です。
起動して、「Hello from JNI C++ ! Compiled with ABI x86.」
ということで完成です。
今回は ndk-build を手動で行いましたが、Gradle の設定をすれば Android Studio からも ndk-build を走らせることができます。
おしまい。
ディスカッション
コメント一覧
まだ、コメントがありません