使用 SWIG 从 Ruby 调用 C 回调

Posted

技术标签:

【中文标题】使用 SWIG 从 Ruby 调用 C 回调【英文标题】:Calling C callback from Ruby using SWIG 【发布时间】:2011-04-27 14:15:22 【问题描述】:

我正在尝试通过 SWIG (2.0.3) 为 C 库创建与 Ruby 的绑定。 比如说,我们在 C 语言中有一个函数原型,内容如下:

void do_sth_and_call_me_then( (int)(* my_callback)(GlyQuery *, GlyMemCache *))

这会做一些奇怪的事情并最终调用回调:

int my_callback(GlyQuery * a, GlyMemCache * b)

多次作为参数给出。由于这是与库交谈的常用方式,因此我也希望在 Ruby 中具有这种行为。在研究过程中,我发现了this,这正是我所需要的:

%
void
wrap_callback(void *user_data, const char *other_data)

  VALUE proc = (VALUE)user_data;
  rb_funcall(proc, rb_intern("call"), 1, rb_str_new2(other_data));

%

遗憾的是,我无法弄清楚我必须进行哪些更改才能使其适用于字符串以外的对象。

如果您需要更多信息:整个接口文件是here

有什么建议吗? 感谢您的帮助。

【问题讨论】:

【参考方案1】:

你应该创建一个回调函数的包装器,因为 C 库不能直接调用 ruby​​ 函数。

在这个包装器中,您应该将结构转换为可以传递给 ruby​​ 代码的东西,因为 ruby​​ 不能直接使用 C 结构。

有一个解决方案允许 ruby​​ 代码访问 C 结构,在此处描述 Wrapping C structs with SWIG

【讨论】:

谢谢,但我的问题是自己编写包装器。 (另请参阅上面的链接)我不确定如何在 wrap_callback() 中表示我的结构 我添加了另一个问题的链接,其中描述了使用结构。您可以发布 SomeStruct 和 OtherStruct 的详细信息吗? 我添加了一个指向接口文件的链接,这可能是为您提供所有详细信息的最佳方式:-) - 还重命名了结构以反映现实:SomeStruct -> GlyQuery, OtherStruct -> GlyMemCache您添加的链接没有多大帮助,因为包装部分工作得很好,只是回调让我头疼。

以上是关于使用 SWIG 从 Ruby 调用 C 回调的主要内容,如果未能解决你的问题,请参考以下文章

SWIG (Java):如何将带有回调函数的结构从 Android 应用程序传递给 C++?

带有回调的 SWIG C++ 绑定

通过 SWIG 从 Ruby 调用 Boost?

使用 SWIG 包装对象从 C++ 调用 Python 函数的最简洁方法是啥

swig官方go Examples 源码勘误

swig -c++ 选项破坏纯 C 文件的包装,错误 C3861:unresolved externals