コールバックといえども、関数呼び出しに代わりはなかろう。
関数というか、メソッド呼び出し。
そう考えると、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 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。