将java函数注册为C函数中的回调 [英] registering java function as a callback in C function

查看:28
本文介绍了将java函数注册为C函数中的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 SWIG 1.3 在 Java 中实现一些 C 代码.现在我必须将一些现有的 C 重新构建为 Java 代码并提供一个函数指向 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.

C 代码:net.c:

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 );
}

我在 Java 中已经拥有的是:

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 ) {}

这应该以与在以上 C 代码,现在在 Java 中:

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);

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

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?

我也找到了 C++ 的解决方案,但是有没有办法让它适应 C?带 Java 的 Swig c++ 在多态回调函数上丢失类型形态回调函数

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

感谢您的帮助.

推荐答案

我还记得 SWIG 手册中的这个参考资料让我抓狂.

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

您可以在没有深奥功能的情况下执行以下操作:

You can do this as follows without the esoteric features:

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

  • 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.

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

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.

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

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

回调进入的线程需要附加到 Java VM(使用 JNI 函数 AttachCurrentThread()).这是您获取 JNIEnv 指针的地方.此指针仅在您从中调用 AttachCurrentThread() 的线程的上下文中有效!这意味着如果您有多个线程上的回调,您需要将 JNIEnv * 缓存在线程本地存储中.

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.

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

Make sure you check return values after returning from JNI functions

确保在所有回调到 Java 后检查 ExceptionOccurred().不这样做真的会给你带来难以调试的麻烦.

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.

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

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.

这篇关于将java函数注册为C函数中的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆