gpt4 book ai didi

rust - 在 C++ 和 Rust 之间来回传递 Rc>

转载 作者:行者123 更新时间:2023-12-03 11:28:13 25 4
gpt4 key购买 nike

根据我这个问题的回答:How to hold Rust objects in Rust code created through C++?我可以将在 Box 中用 Rust 分配的东西传回给 C , 然后再次接收它作为对 &T 的引用, 因为 Rust 分配了 Sized尊重 C ABI 的结构。

我想做同样的事情,但现在是 Rc<RefCell<T>> .我应该返回 Box 吗?到 Rc<RefCell<T>> ?我猜它不是因为Rc不执行 Sized ,这是 T 所必需的在Box<T> according to the Box page .所以这是行不通的:

#[no_mangle]
pub extern "C" fn foo_new() -> Box<Rc<RefCell<T>>> {
Box::new(Foo { glonk: false })
}

我怎样才能使这项工作?基本上我需要创建一个 Rust 结构,它可以被许多人访问,并且可以被其中之一可变地借用。这就是为什么我选择 Rc<RefCell<T>> .是否有另一种类型的结构可以满足我的要求并且对 C 语言友好?

最佳答案

两个智能指针Rc<T>Box<T> 确实是大小类型,它们实现了Sized .此信息未在文档中提供,可能是因为 Sized 的特殊性质: 它总是自动派生为适用的所有类型,并且无法添加或取消该实现(与 SendSync 不同)。

除此之外,将另一个智能指针封装到 Box 中几乎没有什么好处。 .如果打算将实际的智能指针 ( Rc ) 移动到 C FFI 边界并返回,则只需记住一件事:Rc<T> 的布局。与原始指针不兼容,即使 TSized (unlike Box<T> )。

因此,我们需要将其转换为原始指针并显式返回。函数 into_rawfrom_raw也可用于 Rc .

/// create a new Foo and give it to caller
#[no_mangle]
pub extern "C" fn foo_new() -> *const RefCell<Foo> {
Rc::into_raw(Rc::new(RefCell::new(Foo { glonk: false })))
}

/// clone the pointers into two
#[no_mangle]
pub extern "C" fn foo_clone(foo: *const RefCell<Foo>) -> (*const RefCell<Foo>, *const RefCell<Foo>) {
unsafe {
let ptr = Rc::from_raw(foo);
let c = Rc::clone(ptr);
(ptr, c)
}
}

/// get a property of a Foo without returning ownership
#[no_mangle]
pub extern "C" fn foo_glonk(foo: *const RefCell<Foo>) -> bool {
unsafe { (*foo).borrow().glonk }
}

/// return ownership of the Foo,
/// so it can be freed in Rust-land
#[no_mangle]
pub extern "C" fn foo_return(foo: *const RefCell<Foo>) {
let _ = Rc::from_raw(foo);
}

关于rust - 在 C++ 和 Rust 之间来回传递 Rc<RefCell<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62467343/

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