当前位置: 首页 > 面试题库 >

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

穆飞龙
2023-03-14
问题内容

我正在尝试通过使用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并未提供支持通常允许用目标语言编写回调函数,这可以通过使用类型映射和其他高级SWIG功能来完成。这将在下一章中进行描述。”
这指的是哪里?

我也找到了C ++的解决方案,但是有没有办法使它适应C? 具有Java的Swig C
++在多态回调函数 morphic-callback-functions
上丢失类型

谢谢你的帮助。


问题答案:

我记得我也曾在SWIG手册中对此参考挠头。

您可以按以下步骤进行操作,而无需使用深奥的功能:

  • 您需要一种将传入的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附加到该过程。您可以在任一侧设置断点。



 类似资料:
  • 扩展内可以调用registerFunction来注册内置函数到PHP中。需要注意Zend有限制,必须在Extension对象创建时注册函数。这与类的注册不同,扩展类必须在onStart回调中注册。 PHPX_EXTENSION() { Extension *ext = new Extension("test", "0.0.1"); ext->registerFunction(PHP

  • void register_function(string name, mixed impl, bool cacheable, array or null cache_attrs) Use this to dynamically register template function plugins. Pass in the template function name, followed by t

  • void register_compiler_function(string name, mixed impl, bool cacheable) Use this to dynamically register a compiler function plugin. Pass in the compiler function name, followed by the PHP function t

  • 出于某种原因,在下面的递归函数中, 永远不递增p,也就是说字符串s永远不是一个回文,尽管在我的程序中,s确实是一个回文,次数相当少。但是在下面一行中它仍然返回false 是因为功能吗?s采用的一些值为:aaa、aba、AAAA、abbb、bab 我已确保s中没有前后空格 P、 S:我已经检查过了,x==n 示例输入: 输出0。回文:aaaaaa、abaaba、aaaaaa

  • 对于< code>ValueData(或类似的属性),是否有函数的返回值。已尝试以下方法: 但这只是将字符串< code > get computer name string()添加到注册表项中。

  • 假设我们有我的代码的简化版本: 我试图将lambda函数作为参数传递给函数,但只有当我将lambda显式分配给特定的类型时,它才起作用。这是可行的: 上面的例子是可行的,但我想实现下面的例子,因为审美的原因,不知道这是否可能: 我唯一的要求是应该接受带有模板化返回类型的lambda和函数,以及带有特定类型的输入参数,例如。