2011.11.10
【Android NDK】C側からJavaのプログラムを呼び出す
できるらしいのでメモっておく。
/** * c側からjavaを呼び出すテスト * JnitestActivity.callJniを呼び出す */ jvoid Java_test_jni_JnitestActivity_callbackJNI( JNIEnv* env, jobject thiz ) { //クラス取得 jclass jcls = (*env)->GetObjectClass( env, thiz ); //メソッド取得 jmethodID mj = (*env)->GetMethodID( env, jcls, "callJni", "()V"); //メソッド呼び出し (*env)->CallObjectMethod( env, thiz, mj ); }
1. クラス情報を取得する
まずは対象となるjclassを取得する必要がある。
対象オブジェクトがあるときはGetObjectClass、
名前で指定するときはFindClassを使うとよいらしい。
2. メソッドIDを取得する
クラス内のどのメソッドを使うかを決定します。
今回は通常のメソッドを使うのでCallObjectMethodを使います。
staticのメソッドIDを取得するときにはGetStaticMethodIDを使います。
javaは同じ名前で引数が違うものが複数存在できるので、
メソッド名と呼び出したいメソッドの引数や戻り値(シグネチャ)を指定してします。
シグネチャについてはここを参照
Link:JNIコーディングメモ(Hishidama's Java native interface coding Memo)
javapを使うと指定するシグネチャを取得できて便利。
プロジェクトディレクトリのbin\classesへ移動し以下のように
クラスを指定するとこんな感じに出力される
jnitest\bin\classes>javap -s test.jni.JnitestActivity Compiled from "JnitestActivity.java" public class test.jni.JnitestActivity extends android.app.Activity{ static {}; Signature: ()V public test.jni.JnitestActivity(); Signature: ()V public void onCreate(android.os.Bundle); Signature: (Landroid/os/Bundle;)V public void callJni(); Signature: ()V public native java.lang.String stringFromJNI(); Signature: ()Ljava/lang/String; public native java.lang.String Test(java.lang.String); Signature: (Ljava/lang/String;)Ljava/lang/String; public native java.lang.String loadText(java.lang.String, java.lang.String); Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; }
Signatureに出ているものをそのまま指定すればjmethodIDが取得できます。
3. メソッドを呼び出す
CallObjectMethodでメソッドを呼び出します。
引数に対象のクラスとメソッドIDとメソッドに必要な引数を渡します。
staticメソッドはCallStaticObjectMethodというのがある。
・JNIコーディングメモ(Hishidama's Java native interface coding Memo)
・Java/JNI - PukiWiki
こんな感じで何かしら問題があった場合はjava側へ処理を任せる
みたいなこともできます。
処理が面倒なものやイベント送信とかに使うといいかもしれません。
Android NDKネイティブプログラミング 出村 成和 秀和システム 2011-07 |
関連記事