コールバックといえども、関数呼び出しに代わりはなかろう。
関数というか、メソッド呼び出し。
そう考えると、StringBuffer.append()を呼び出したようなしくみでいいはず。
と、自分一人で解決できたように書いているが、そんなことはない。
bitlogさんの記事を見て、ようやくできた。
package com.jnitest; class Jni { public static void main(String[] args) { System.out.println("Hello"); callCallback("callbackFunc"); } public void callbackFunc() { System.out.println("callback"); } static { System.loadLibrary("jnicallback"); } public static native void callCallback(String funcName); } |
#include "com_jnitest_Jni.h" JNIEXPORT void JNICALL Java_com_jnitest_Jni_callCallback (JNIEnv *env, jclass clazz, jstring funcName) { const char* fname = (*env)->GetStringUTFChars(env, funcName, NULL); jclass jc = (*env)->FindClass(env, "com/jnitest/Jni"); jmethodID mid = (*env)->GetMethodID(env, jc, fname, "()V"); if(mid) { jmethodID ctor = (*env)->GetMethodID(env, jc, "<init>", "()V"); jobject jo = (*env)->NewObject(env, jc, ctor); (*env)->CallVoidMethod(env, jo, mid); (*env)->DeleteLocalRef(env, jo); } else { printf("mid is null.\n"); } (*env)->ReleaseStringUTFChars(env, funcName, fname); (*env)->DeleteLocalRef(env, jc); } |
$ java com.jnitest.Jni
Hello
callback
よくわかってないのが、なぜCallVoidMethod()するのにjobjectが必要なのかということ。
NewObject()しているから、これはJava_com_jnitest_Jni_callCallback()を呼び出した人とは別の人になっていると思う。
引数のclazzから取ってくることはできないのかな?
まず、jcを取り除き、clazzに置き換える・・・よし、動いた。
あれ、jclassからオブジェクトを取ってくる関数はないな。
そもそもメソッドなのにjclassが引数で渡されるなんておかしいのでは?
・・・自分でpublic static nativeって書いとるやん。
そしてコールバックして呼び出そうとする方は非staticだ。
これがいかんのですな。
そんなわけで、コールバックする方もstaticにするか、nativeを非staticにするか、だ。
今回はmain()から呼び出すので、コールバックする方をstaticにした。
package com.jnitest; class Jni { public static void main(String[] args) { System.out.println("Hello"); callCallback("callbackFunc"); } public static void callbackFunc() { System.out.println("callback"); } static { System.loadLibrary("jnicallback"); } public static native void callCallback(String funcName); } |
#include "com_jnitest_Jni.h" JNIEXPORT void JNICALL Java_com_jnitest_Jni_callCallback (JNIEnv *env, jclass clazz, jstring funcName) { const char* fname = (*env)->GetStringUTFChars(env, funcName, NULL); jmethodID mid = (*env)->GetStaticMethodID(env, clazz, fname, "()V"); if(mid) { (*env)->CallVoidMethod(env, clazz, mid); } else { printf("mid is null.\n"); } (*env)->ReleaseStringUTFChars(env, funcName, fname); } |
$ java com.jnitest.Jni
Hello
callback
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。