Rust 通过Rc<;RefCell<;T>&燃气轮机;在C和x2B之间来回+;生锈

Rust 通过Rc<;RefCell<;T>&燃气轮机;在C和x2B之间来回+;生锈,rust,Rust,根据我对这个问题的回答:我可以将在框中的Rust中分配的东西传递回C,然后再次接收它作为对&T的引用,因为Rust根据C ABI分配大小的结构 我想做同样的事情,但是现在对于Rc。我是否应该将框返回到Rc?我猜不会,因为Rc没有实现size,这是框中T所必需的。所以这是行不通的: #[no_mangle] pub extern "C" fn foo_new() -> Box<Rc<RefCell<T>>> { Box::new(Foo { glo

根据我对这个问题的回答:我可以将在
框中的Rust中分配的东西传递回C,然后再次接收它作为对
&T
的引用,因为Rust根据C ABI分配
大小的
结构

我想做同样的事情,但是现在对于
Rc
。我是否应该将
框返回到
Rc
?我猜不会,因为
Rc
没有实现
size
,这是
框中
T
所必需的。所以这是行不通的:

#[no_mangle]
pub extern "C" fn foo_new() -> Box<Rc<RefCell<T>>> {
    Box::new(Foo { glonk: false })
}
#[无损坏]
pub extern“C”fn foo_new()->Box{
框::新建(Foo{glonk:false})
}

我怎样才能做到这一点?基本上,我需要创建一个Rust结构,它可以被许多人访问,并且可以被其中的一个借用。这就是为什么我选择了
Rc
。是否有另一种类型的结构可以实现我想要的功能并对C友好?

智能指针
Rc
Box
确实是大小类型,它们实现
size
。文档中未显示此信息,可能是因为
大小的
的特殊性质:它总是自动为适用的所有类型派生,并且不能添加或取消该实现(与
发送
同步

这样一来,将另一个智能指针封装到
框中就没有什么好处了。如果打算将实际智能指针(
Rc
)跨C FFI边界来回移动,则只需记住一件事:
Rc
的布局与原始指针不兼容,即使
T
大小为
时也是如此

因此,我们需要将其转换为原始指针并显式返回。
进入_raw
自_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);
}
///创建一个新的Foo并将其交给调用者
#[没有损坏]
pub extern“C”fn foo_new()->*const RefCell{
Rc::into_raw(Rc::new(RefCell::new(Foo{glonk:false})))
}
///将指针克隆为两个
#[没有损坏]
pub extern“C”fn foo_clone(foo:*const RefCell)->(*const RefCell,*const RefCell){
不安全{
设ptr=Rc::from_raw(foo);
设c=Rc::clone(ptr);
(ptr,c)
}
}
///在不返回所有权的情况下获取Foo的属性
#[没有损坏]
酒吧外部“C”fn foo_glonk(foo:*const RefCell)->bool{
不安全的{(*foo.borrow().glonk}
}
///归还Foo的所有权,
///所以它可以在锈迹斑斑的土地上被释放
#[没有损坏]
酒吧外部“C”fn foo_return(foo:*const RefCell){
让u=Rc::from_raw(foo);
}

Rc
确实实现了
大小
。你是如何得出相反的结论的?@E_net4我在Rust网站的Rc页面上找不到
impl size for Rc
。所以我应该使用
?我不能简单地使用
Rc
?我找不到它是否具有与
Box
相同的属性(即,它的内存布局类似于C布局)