如何从Android应用程序注册回调JNI?我的要求是,我想从Android应用程序进行JNI调用,并希望注册回调,以便我可以从JNI回调java应用程序。
由于
答案 0 :(得分:0)
首先,看看Swig。它用Java包装C ++,并且还具有“导向器”功能,可以更容易地从Java调用C ++方法。
使用原始JINI,您无法直接执行此操作。虽然RegisterNatives()调用可以绑定本机方法,但不能更改。如果要通过指针调用C函数,则需要分两步完成。我经常光顾,因为JNI令人难以置信的冗长乏味。基本技巧是,将C函数指针包装在java long中。
首先声明一个java类:
public class Callback {
public Callback(long cMethodPointer) { this.cMethod = cMethod; }
public void doCallback() { callCMethod(cMethod); }
public static native void callCMethod(long cMethod);
public long cMethod;
}
在该类文件上运行javah,您将获得一个生成的存根标题,如下所示:
JNIEXPORT void JNICALL Java_Callback_callCMethod
(JNIEnv *, jclass, jlong);
在DLL /中实现该方法:
typedef void (*FP)();
JNIEXPORT void JNICALL Java_Callback_callCMethod
(JNIEnv *, jclass, jlong pointer) {
((FP)(void*)pointer)();
}
并在Java main()方法中调用该DLL上的System.loadLibrary()。
最后,从你的C / C ++代码中,你需要通过JNI创建一个Callback对象的实例,并将指针传递给它的实际方法:
void MyFunction() { ... }
void Register() {
jclass cls = env->FindClass("Callback");
jmethodID mid = env->GetMethodID(cls, "<init>", "(J)V");
jvalue arg;
arg.j = (jlong)(void*)MyFunction;
jobject callback = env->NewObjectA(confCls, mid, &arg);
}
因此,这为您提供了一个全新的Callback对象,指向您的C函数!但那么,你怎么做呢?好吧,你必须通过JNI将Callback对象传递给Java(步骤省略),这样你的Java代码就有了Callback对象,可以从中调用你的C方法:
public class Foo {
public Callback callback;
public void doSomeStuff() {
...
callback.doCallback();
}
}