java注册c的回调函数,在C函数中注册java函数作为回调

I am trying to implement some C code in Java by using SWIG 1.3. Now I

have to rebuild some existing C into Java code and to provide a function

pointer to a Java function to the C method.

The C code:

net.c:

void register_message_handler( context_t *ctx, message_handler_t handler) {

context->msg_handler = (void (*)( void *, coap_queue_t *, void *)) handler;

}

client.c:

void message_handler(context_t *ctx, queue_t *node, void *data) {

...

}

int main(int argc, char **argv) {

// setup ctx

register_message_handler( ctx, message_handler );

}

All I already have in Java is:

public static void message_handler(def.SWIGTYPE_p_context_t ctx, def.SWIGTYPE_p_queue_t node, String data ) {}

and this should be registered as callback in the same way as it is done in the

above C code, now in Java:

net.register_message_handler(ctx, message_handler);

What I found was

http://www.swig.org/Doc1.3/SWIGDocumentation.html#SWIG_nn30 including an

undefined reference at the end of this chapter:

"And now, a final note about function pointer support. Although SWIG does not

normally allow callback functions to be written in the target language, this

can be accomplished with the use of typemaps and other advanced SWIG features.

This is described in a later chapter."

Where does this refer to?

I also found a solution for C++, but is there a way to adapt this to C?

Swig c++ w/ Java loses type on polymorphic callback functions

morphic-callback-functions

Thanks for your help.

解决方案

I remember scratching my head over this reference in the SWIG manual too.

You can do this as follows without the esoteric features:

You need a mechanism to dispatch the incoming C callback into Java. For that you need the object ID of the object that you are calling into, and the method ID of your handler. In your C registration helper, create Global References for those and cache them for use by the callback.

You also need a class ID and constructor method ID for anything that you want to pass to the java callback as a parameter. You also want to cache Global References to those.

In the C part of the callback, look up your method IDs, construct arguments and call into Java.

The thread that the callback comes in on, needs to be attached to the Java VM (with the JNI function AttachCurrentThread()). This is where you get your JNIEnv pointer from. This pointer is only valid in the context of the thread that you invoked AttachCurrentThread() from! What this means is that if you have callbacks coming in on multiple threads, you need to cache the JNIEnv * in thread local storage.

Make sure you check return values after returning from JNI functions

Make sure to check ExceptionOccurred() after any and all calls back into Java. Not doing this really gets you in trouble in hard to debug ways.

I found this relatively easy to debug with Eclipse and Visual Studio as follows: Start main Java program from Eclipse, attach Visual Studio Debugger to that process. You can set breakpoints on either side.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值