如何创建 Rust 回调函数以传递给 FFI 函数?

Posted

技术标签:

【中文标题】如何创建 Rust 回调函数以传递给 FFI 函数?【英文标题】:How do I create a Rust callback function to pass to a FFI function? 【发布时间】:2015-10-06 10:38:00 【问题描述】:

这就是 C API 的样子

void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int));

rust-bindgen 为我生成了这个

pub fn mosquitto_connect_callback_set(
    mosq: *mut Struct_mosquitto,
    on_connect: ::std::option::Option<
        extern "C" fn(
            arg1: *mut Struct_mosquitto,
            arg2: *mut ::libc::c_void,
            arg3: ::libc::c_int,
        ) -> (),
    >,
)

如何创建一个 Rust 回调函数以传递给上述 Rust 绑定中的on_connect 参数?

【问题讨论】:

【参考方案1】:

The Rust Programming Language第一版,有一个关于 FFI 的部分,标题为 Callbacks from C code to Rust functions。

那里的例子是

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


#[link(name = "extlib")]
extern "C" 
    fn register_callback(cb: extern "C" fn(i32)) -> i32;
    fn trigger_callback();


fn main() 
    unsafe 
        register_callback(callback);
        trigger_callback(); // Triggers the callback
    

对于您的具体情况,您已经知道您需要的具体功能类型:

extern "C" fn mycallback(
    arg1: *mut Struct_mosquitto,
    arg2: *mut ::libc::c_void,
    arg3: ::libc::c_int,
) -> () 
    println!("I'm in Rust!");

然后像这样使用它

mosquitto_connect_callback_set(mosq, Some(mycallback));

【讨论】:

我不会从 C 中调用 rust 函数。在我的 rust 代码中,我想将一个参数传递给 on_connect 参数。 @tez “我不会从 C 调用中调用 rust 函数” — 但您特别问 “如何创建 rust 回调函数?” 。这就是回调。也许您只是在问如何使用 mosquitto API,而不是 Rust 特有的任何东西? 好的。这可能会造成一些混乱。但是,通过回调函数,我的意思是“作为参数传递给其他函数的函数” @tez 这正是答案中的两个示例所显示的。查看对register_callbackmosquitto_connect_callback_set 的调用。 对不起。我的错。我以为您指的是“如何从 C 调用 rust 函数”。

以上是关于如何创建 Rust 回调函数以传递给 FFI 函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用字符串作为参数从 Go 调用 Rust 函数?

如何从 NodeJS 中的 Rust FFI 函数返回字符串值?

通过 FFI 调用 Rust 函数时访问冲突

将额外变量传递给回调函数

如何将 Rust `Vec<T>` 暴露给 FFI?

如何在 Rust 中表示指向 C 数组的指针?