JNIでJavaから簡単にネイティブを呼べるのは知っていたんですが、ネイティブからJavaの呼び出しもこんなに簡単なんですね。
まるでリフレクションのようにCからJavaを呼び出せるなんて。
メソッド呼び出し、オブジェクトの生成はもちろんのこと、スーパークラスのprivateメソッドでも呼び出せるしフィールドの参照もできる。もちろんヘッダファイルとかには何も書いてないのに呼べる。
すげ〜まじすげ〜
やり方はとても簡単でまずJavaから普通にJNIでCを呼び出す。そして自分のクラスの参照を渡してグローバル参照にいれておく。もしくは最初からJNIでコンストラクタを呼び出してクラスを生成してもいいはず。グローバル参照に入れるのはJNI呼び出しが終わっても自動的に解放されないようにするため。
JNIEXPORT void JNICALL Java_c2java_setListener (JNIEnv *env, jclass, jobject obj) { listener = env->NewGlobalRef(obj); //グローバル参照取得 }
後はこのクラスを使っていつでも好きなタイミングでJavaメソッドをコールしたりフィールド値をCから取得できる。
メソッドの呼出はこんな感じ。
//java の void garapon(String str) を呼ぶ jmethodID func = env->GetMethodID(clsj, "garapon", "(Ljava/lang/String;)V"); jstring encj = NULL; encj = env->NewStringUTF("I am GARAPON!!!"); env->CallVoidMethod(listener, func, encj);
Cでクリップボードの値を監視して変化があったらJavaのメソッドに通知するなんてのが間単に作れた。(何の意味があるのかまったくわからないアプリだがw)
使う用途はかなり限られるけどここまで自由に出来るとかなり面白い。
JNI++