你能从生锈的c库中运行防锈代码吗?

时间:2014-01-07 09:20:42

标签: rust

我查看了rust foreign function interface,并且成功(并且愉快地)可以从我的防锈代码中调用c库。

但是,我似乎无法在c代码范围内找到有关如何注册回调以调用防锈代码的任何细节。

这甚至可能吗?

作为'为什么你会这样做?'的理由?具体来说,我正在考虑在一个生锈应用程序中嵌入lua或python,并为在嵌入式运行时运行的脚本公开脚本api。

调用这些将是:

  • 主要施工负荷
  • 应用程序使用ffi初始化脚本运行时
  • 应用程序将本地防锈功能绑定到C-callbacks
  • 应用程序调用ffi将C回调绑定到脚本层
  • 应用程序运行〜
  • 定期ffi用于触发脚本运行时执行字节码块
  • 脚本代码执行各种简单的逻辑并调用绑定句柄
  • 绑定句柄调用c代码
  • 绑定的c代码调用本地防锈代码

所有这些步骤除了粗体之外我已经设法工作了,而且我已经完成了一些使用调度程序的简单工作,C调用将“运行我”命令转储到队列中并在控制时返回到rust范围,应用程序查询队列并运行其中的命令......

...但是从脚本方面来看有点尴尬,因为它意味着多个嵌套的异步回调,而脚本层的重点是简化需要进入脚本层的代码。

1 个答案:

答案 0 :(得分:11)

是的,您可以将一个回调函数从Rust传递给C并在那里调用它。 要知道的主要事情是你必须使用extern“C”属性定义函数。

未经测试的示例(此处没有Rust编译器):

生锈的一面:

extern "C" fn callback(a:i32) {
    println!("I'm called from C with value {0}", a);
}

#[link(name = "mylib")]
extern {
   fn register_callback(cb: extern "C" fn(i32)) -> i32;
}

fn main() {
    unsafe {
        register_callback(callback);
    }
    ...
}

C方:

typedef void (*rust_callback)(int32_t);
rust_callback cb;

int32_t register_callback(rust_callback callback) {
    cb = callback;
    return 1;
}

void thread() {
  // do sth
  cb(xyz);
}