将java函数注册为C函数中的回调函数

我试图使用SWIG 1.3在Java中实现一些C代码。 现在我必须将一些现有的C重建为Java代码,并为C方法提供指向Java函数的函数指针。

C代码: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 ); } 

我在Java中已经拥有的是:

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

这应该以与上面的C代码相同的方式注册为回调,现在是Java:

 net.register_message_handler(ctx, message_handler); 

我发现的是http://www.swig.org/Doc1.3/SWIGDocumentation.html#SWIG_nn30,包括本章末尾的未定义引用:“现在,关于函数指针支持的最后一点说明。虽然SWIG没有通常允许回调函数以目标语言编写,这可以通过使用类型映射和其他高级SWIGfunction来完成。这将在后面的章节中描述。 这指的是哪里?

我也找到了一个C ++解决方案,但有没有办法让它适应C? swig c ++ w / Java在多态回调函数 morphic-callback-functions 上丢失类型

谢谢你的帮助。

我还记得在SWIG手册中对此引用的讨论。

你可以这样做,没有深奥的function:

  • 您需要一种机制将传入的C回调分派到Java中。 为此,您需要要调用的对象的对象ID以及处理程序的方法ID。 在C注册助手中,为这些创建全局引用并缓存它们以供回调使用。

  • 对于要作为参数传递给java回调的任何内容,还需要类ID和构造函数方法ID。 您还想将全局引用缓存到那些。

  • 在回调的C部分中,查找方法ID,构造参数并调用Java。

  • 回调所在的线程需要连接到Java VM(使用JNI函数AttachCurrentThread())。 这是从中获取JNIEnv指针的地方。 该指针仅在您调用AttachCurrentThread()的线程的上下文中有效! 这意味着如果你有多个线程上的回调,你需要在线程本地存储中缓存JNIEnv *。

  • 确保从JNI函数返回后检查返回值

  • 确保在任何和所有调用回Java之后检查ExceptionOccurred()。 不这样做真的让你在难以调试方面遇到麻烦。

  • 我发现使用Eclipse和Visual Studio调试相对容易,如下所示:从Eclipse启动主Java程序,将Visual Studio Debugger附加到该进程。 您可以在任何一侧设置断点。