gpt4 book ai didi

c++ - 是否可以在 Rust 中接收指向 C 函数的指针并将其回调?

转载 作者:行者123 更新时间:2023-12-01 15:10:41 28 4
gpt4 key购买 nike

我正在学习如何连接 Rust 和 C++(使用 C 接口(interface))。这是 Mozilla 的 Android 上 Rust 指南中的一个示例:

use std::os::raw::{c_char};
use std::ffi::{CString, CStr};

#[no_mangle]
pub extern fn rust_greeting(to: *const c_char) -> *mut c_char {
let c_str = unsafe { CStr::from_ptr(to) };
let recipient = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};

CString::new("Hello ".to_owned() + recipient).unwrap().into_raw()
}

如您所见,需要一个 C char 指针,它也返回一个 C char 指针。

我想在我的项目中使用 Rust 代码作为库。这个 Rust 代码会在数据包准备好时将它们发送给我。因此,我需要一种将回调传递给 Rust 的方法,以便它可以在有数据时回调它。有点像这个 C++ 片段:
extern "C" onData(uint8_t* payload, size_t size) {
//do something with payload
}

MyRustType myRustObject("initialization_string");
myRustObject.setOnDataCallback(&onData);
myRustObject.beginWork();

所以, rust '类', MyRustType ,将开始工作并通过 onData 发送数据包.是否可以将 C 函数作为指向 Rust 的指针传递?

如果没有,我可以将指针作为 uint64_t 传递数字,并让 Rust 将此数字 + 有效负载传递回一个 C 函数,该函数又将这个 uint64_t 指针转换为函数并使用有效负载调用它。但我认为,由于 Rust 对 C 非常友好,所以有更好的方法来做到这一点。

最佳答案

你可以从 C 到 Rust 以及从 Rust 到 C 自由但不安全地调用。

从 Rust 到 C:写一个 extern "C" block 与 C 函数的原型(prototype)。

从 C 到 Rust:使用 #[no_mangle] extern "C" 编写 Rust 函数字首。您必须确保接收或返回的任何值都是 FFI 友好的:基本类型或 repr(C)类型或指向这些和其他一些的原始指针。

您还需要与 Rust 等效的 C 声明。为此,您可以使用 std::os::raw 中的类型, std::ffi和外部 crate libc .

特别是关于函数指针的问题的答案,例如 C 中的这种类型:

typedef int (*callback)(uint8_t *data, size_t len);

被翻译成 Rust 为:
type Callback = unsafe extern "C" fn(data: *mut u8, len: usize) -> c_int;

此类型 Callback是 FFI 友好的,所以你可以存储它,在 Rust 和 C 之间传递,并在你想要的时候调用它。当然,您可以在其他 FFI 声明中将其用作参数或返回类型:
int do_the_thing(uint8_t*data, size_t len, callback cb);
#[no_mangle]
pub extern "C" fn do_the_thing(
data: *const u8, len: usize,
cb: Option<Callback>) -> c_int)
{
//...
}

请记住,在 Rust 中,指针函数是不可为空的,所以如果你希望 C 能够传递 NULL您使用 Option<fn> .

有关 Rust 中 FFI 的更多详细信息,您可以阅读 this chapter of the Rustonomicon .

关于c++ - 是否可以在 Rust 中接收指向 C 函数的指针并将其回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61671255/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com