首页 > 解决方案 > 如何创建 UnsafeCell安全吗?

问题描述

UnsafeCell 文件说_

UnsafeCell<T>类型是获取被认为是可变的可别名数据的唯一合法方式。

唯一的构造方法是:

pub const fn new(value: T) -> UnsafeCell<T>

但是,不可能创建 a c_void,我们只能创建*mut c_voidor *const c_void

是否可以从UnsafeCell<c_void>创建*mut c_void?有了这个,我们可以让编译器知道指针可以指向可变的东西。

或者这不是必需的吗?*mut c_void即使我们知道某些 FFI 调用会改变它指向的数据并且我们对它有多个引用,我们是否可以一直使用它?

一个用例是:

struct FFIStruct { v: UnsafeCell<c_void>, other_fields: ... }
impl FFIStruct {
    // We don't want to require &mut self, as we 
    // are sure private call_ffi() will always be called 
    // sequentially, and we don't want to stop
    // status() being callable during the call
    fn call_ffi(&self){ ffi_function(self.v.get()) }
    pub fn status(&self) -> FFIStatus { ... }
}

现在我们如何创建FFIStruct?或者只是使用*mut c_void就可以了?

创建示例代码&Cell<c_void>

要求#![feature(as_cell)]

unsafe fn get_cell<'a>(p: *mut c_void) -> &'a Cell<c_void> {
    Cell::from_mut(&mut *p)
}

标签: rustunsafe

解决方案


TL;DR:只需使用*mut Foo. 这里不需要任何类型的细胞。


免责声明:目前还没有正式的 Rust 内存模型。

无法创建此类型 period,因为您无法1创建c_void.

问题是,您不需要创建这样的类型。混叠不是空间的而是时间的。您可以有多个*mut T指向同一个地方,直到您尝试访问一个. 这实质上将其转换为参考,并且在参考存在时需要维护别名要求。

原始指针不属于 Rust 的安全内存模型。

锈书

与引用和智能指针不同,原始指针:

  • 允许通过同时拥有不可变和可变指针或指向同一位置的多个可变指针来忽略借用规则
  • 不保证指向有效内存
  • 允许为空
  • 不要实施任何自动清理

¸— Rust 编程语言

也可以看看:

1从技术上讲,您可以,但这只是因为实现和向后兼容性限制。


推荐阅读