rust - 如何创建 UnsafeCell安全吗?
问题描述
UnsafeCell
文件说_
该
UnsafeCell<T>
类型是获取被认为是可变的可别名数据的唯一合法方式。
唯一的构造方法是:
pub const fn new(value: T) -> UnsafeCell<T>
但是,不可能创建 a c_void
,我们只能创建*mut c_void
or *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)
}
解决方案
TL;DR:只需使用*mut Foo
. 这里不需要任何类型的细胞。
免责声明:目前还没有正式的 Rust 内存模型。
您无法创建此类型 period,因为您无法1创建c_void
.
问题是,您不需要创建这样的类型。混叠不是空间的而是时间的。您可以有多个*mut T
指向同一个地方,直到您尝试访问一个. 这实质上将其转换为参考,并且在参考存在时需要维护别名要求。
原始指针不属于 Rust 的安全内存模型。
—锈书
与引用和智能指针不同,原始指针:
- 允许通过同时拥有不可变和可变指针或指向同一位置的多个可变指针来忽略借用规则
- 不保证指向有效内存
- 允许为空
- 不要实施任何自动清理
¸— Rust 编程语言
也可以看看:
- 为什么通过原始指针修改可变引用的值不会违反 Rust 的别名规则?
- 定义指向 C 不透明指针的字段的 Rust 习惯用法是什么?
- 借助 Rust 中的原始指针进行运行时借用管理是未定义的行为吗?
- FFI 函数可以修改未声明为可变的变量吗?
1从技术上讲,您可以,但这只是因为实现和向后兼容性限制。
推荐阅读
- python - 如何将来自http请求的几个图像图块写入python中的新图像对象?
- c - 我是编程和学习 C 的新手,我的问题是关于按人名的索引打印一封信
- java - Java 是否翻转文件 I/O 中的字节顺序?
- react-native - react native web view set source 三元
- arduino - PIR 传感器与其他传感器一起使用时始终为高电平
- swift - 为什么我的组合 httpMethod 发布请求不起作用?
- tableau-api - 如何创建从星期一开始的一周至今的 Tableau 计算
- reactjs - localstorage 在页面刷新时在 react-redux 应用程序中返回“未定义”
- macos - 如何调试为什么 cURL 不在命令行上显示响应?
- ios - 当您从远程 url 播放 AVAsset 时会发生什么?