c++ - 将泛型对象传递给 Rust 并在使用后传回 C++ 进行销毁
问题描述
我想将缓冲区从 C++ 发送到 Rust,在 Rust 中读取它们并在不再需要它们时在 C++ 上销毁它们。
这是我收到的功能:
#[no_mangle]
pub extern "C" fn smol_stack_smol_socket_send(
smol_stack: &mut SmolStackType,
socket_handle_key: usize,
data: *mut u8,
len: usize,
endpoint: CIpEndpoint,
) -> u8 {
我想接收指向uint8_t
数据的指针,但我也不认为我需要自己使用new uint8_t[size]
. 例如,我可以用一个字符串来做:
std::string* s = new std::string("hello");
然后简单地传递s.c_str()
给uint8_t*
Rust。我不能简单地调用delete[] s.c_str()
,我需要删除s
C++ 端的字符串。所以,我正在考虑向我的函数添加另外 2 个参数smol_stack_smol_socket_send
。一个是指向拥有uint8_t
缓冲区的对象的指针(在本例中是字符串,但也可以是另一个),另一个是指向接收该对象并进行析构的函数的指针。
我想到了类似在 Rust 中将字符串/对象作为 void 指针接收,但我不知道这是否可能。此外,第二个参数,即析构函数,也需要是一个作用于通用数据的函数,因为我可以传递一个与字符串不同的对象,它拥有数据。
这里有什么优雅和安全的解决方案?
解决方案
在我看来,您至少有两条可能的路径。哪一个适合你将在很大程度上取决于这些调用如何组合在一起。
最简单的方法是只考虑从 C++ 传递到 rust 的数据仍然由 C++ 拥有。iesmol_stack_smol_socket_send
预计不会破坏传递给它的缓冲区。那份工作落到了调用者的头上smol_stack_smol_socket_send
。
锈代码可能如下所示:
#[no_mangle]
pub extern "C" fn simpler_function(
data: *mut u8,
len: usize,
) { .. }
然后 C++ 代码将如下所示:
void with_string() {
std::string buffer("Hello World");
simpler_function(buffer.c_str(), buffer.length());
// C++ destroys the string here.
}
void with_newed_buffer() {
char* buffer=new char[10];
buffer[0]='A';
buffer[1]=0;
simpler_function(buffer, 2);
delete [] buffer;
}
另一种方法是将回调传递给函数以处理销毁缓冲区
type Destructor = extern "C" fn(*mut c_void);
#[no_mangle]
pub extern "C" fn core_function(
data: *mut u8,
len: usize,
calback_data: *mut c_void
destructor: Destructor
) {
..
// We're done with the data - destroy it
destructor(callback_data);
}
现在在 C++ 中,代码看起来像这样......
void delete_buffer(void* buffer) {
delete [] (char*)buffer;
}
void with_newed_buffer() {
char* buffer=new char[10];
buffer[0]='A';
buffer[1]=0;
simpler_function(buffer, 2, buffer, delete_buffer);
}
IMO 你应该总是喜欢第一种方法。这不起作用的唯一情况是当 rust 需要获取 C++ 对象的所有权(并因此控制生命周期)时。通常,这意味着将其存储在 rust collection 等的某个地方。
推荐阅读
- javascript - 如何在随机生成的数字上添加函数
- sqlite - 尝试在表中插入 UNIQUE 属性的 NULL 值时出现模棱两可的错误消息
- swift - 无法为多部分表单请求创建数据
- date - 如何将字符串日期格式“2019 年 10 月 18 日”转换为有效日期“2019-10-17T23:00:00.000Z”
- c# - Azure CosmosDB:日期时间问题(时间戳)
- unity3d - Unity Complete Editor 变粉红色 - Unity Editor Bug
- excel - 从excel中的单元格获取电子邮件地址
- python - Django 从 .values_list 查询中删除重复项,同时保留顺序
- bash - Preserve space in value of a variable
- javascript - 单击 Qualtics 中的字段时显示 Datepicker