我听从了
registering java function as a callback in C function并可以使用“简单”类型(如integer和string)进行回调,例如:
jstring js = (*env)->NewStringUTF(env, "hello");
(*env)->CallStaticVoidMethod(env, cls, methodid, js);
但是,如果我试图对用SWIG包装的C数据类型执行同样的操作,那么我在Java中只能得到空指针。在C部分,它们绝对不是0。他们需要区别对待吗?
[编辑:]
更多信息:
如上所述,char*/string也对我有效。我正在寻找一个C struct的解决方案,它已经被SWIG包装并在Java中分配。
例如。:
typedef struct {
unsigned short length;
unsigned short value;
} lv_t;
被SWIG包装,所以我可以在Java中使用它:
lv_t lv;
lv = modulename.modulename_new_lv();
lv.setLength(1);
lv.setValue(2);
然后我将把这个结构从Java转换成C:
modulename.send(lv);
C将通过网络发送,接收一些回复并更改lv中的值。现在,这将把修改后的lv返回给Java。
void jni_call_received_hook(lv_t* lv){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Lcom/something/modulename/jni/lv_t;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
// what to do here to create a jobject?
jobject lv_j = ...;
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, lv_j);
}
它要求:
public static void messageHandler(lv_t lv) {
System.out.println("messageHandler().");
System.out.println("lv " + lv);
}
最佳答案
很抱歉,我还不能对你的问题发表评论,所以这更多的是评论而不是回答。不管怎样,我最近也做过类似的事情。
我的回调工作并实现为:
void jni_call_received_hook(char* username){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Ljava/lang/String;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, (*m_env)->NewStringUTF(m_env, username));
}
变量m_vm是JVM的一个实例,我调用了一个注册了这个回调的方法,如下所示:
JNIEXPORT void JNICALL Java_gui_StateMachine_setCallReceivedCallback(JNIEnv *e, jobject o){
(*e)->GetJavaVM(e, &m_vm );
set_call_received_hook(jni_call_received_hook);
}
也许你丢了什么东西。如果还不够清楚,请告诉我。希望有帮助。