UnsafeCell
文档中说
不完美
唯一的施工方法是:
pub const fn new(value: T) -> UnsafeCell<T>
但是,不可能创建
c_void
,我们只能创建*mut c_void
或*const c_void
。
是否可以创建
UnsecCell
还是没有必要?即使我们知道某个外国金融机构的电话会改变它所指向的数据,并且我们有多个引用,我们是否可以始终使用
*mut c_void
?
一个用例将是:
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
就可以了?
需要
#![功能(as_cell)]
:
unsafe fn get_cell<'a>(p: *mut c_void) -> &'a Cell<c_void> {
Cell::from_mut(&mut *p)
}
在Rust论坛的一些内部讨论和关于RFC 1861的讨论之后,我意识到c_void
只是一个常见的解决方法,并且存在其他选项,例如结构不透明
所以我得出结论,我需要的是
*const UnsafeCell
这是一个原始指针,所以适合立即发送到FFI;
- 原始指针假定
const
,意味着任何对*mut T
的转换都会UB和程序员应该避免它。这可以保护它指向的内存在Rust中被修改(除非通过UnsecCell
,原因); - 它包含
UnsecCell
,因此它意味着内部可变性。这证明FFI函数能够对其进行变异是合理的; - 无法创建
c_void
,因此对于UnsecCell
降级:
use std::cell::UnsafeCell;
use std::os::raw::c_void;
//Let's say all those functions are in an FFI module,
//with the exact same behaviour
fn ffi_create() -> *mut c_void {
Box::into_raw(Box::new(0u8)) as *mut c_void
}
unsafe fn ffi_write_u8(p: *mut c_void, v:u8) {
*(p as *mut u8) = v;
}
unsafe fn ffi_read_u8(p: *mut c_void) -> u8 {
*(p as *mut u8)
}
fn main() {
unsafe {
//let's ignore ffi_destroy() for now
let pointer = ffi_create() as *const UnsafeCell<c_void>;
let ref_pointer = &pointer;
ffi_write_u8((&*pointer).get(), 7);
let integer = ffi_read_u8((&**ref_pointer).get());
assert_eq!(integer, 7);
}
}
有趣的是,在
*mut c_void
和*const UnsafeCell>之间转换是多么容易且符合人体工程学(但又富有表现力)
TL;医生:只需使用*mut Foo
。这里不需要任何类型的细胞。
免责声明:目前还没有正式的锈迹记忆模型。
无法创建此类型period,因为无法1创建c_void
的实例。
问题是,你不需要创建这样的类型。别名不是空间的,而是时间的。你可以让多个*mut
指向同一个地方,这并不重要,除非你尝试访问一个。这实质上是将其转换为一个引用,在该引用存在时,需要支持别名要求。
原始指针不属于Rust的安全内存模型。
-Rustonomicon酒店
与引用和智能指针不同,原始指针:
Rust编程语言
另见:
1从技术上讲,您可以,但这只是因为实现和向后兼容性限制。
问题内容: 检查文件目录是否存在的最优雅方法是什么(如果不存在),使用Python创建目录?这是我尝试过的: 不知何故,我想念(感谢魔芋,布莱尔和道格拉斯)。这就是我现在所拥有的: 是否有“打开”标志,使它自动发生? 问题答案: 在Python≥3.5上,使用: 对于较旧的Python版本,我看到两个质量不错的答案,每个答案都有一个小缺陷,因此我将对此进行说明: 试试看,然后考虑创建。 如注释和其
问题内容: 我正在创建要执行的JEXL脚本的沙箱,以使恶意用户无法访问我们为其提供访问权限的变量之外的数据,也无法在服务器上执行DOS攻击。我想为其他这样做的人提供文档,也让其他人对此方法有所投入。 以下是我知道需要解决的问题的列表: 仅允许使用白名单上的“ new”实例化类。 不允许访问任何类的getClass方法,因为这样便可以调用forName并且可以访问任何类。 限制对文件等资源的访问。
输入安全 虽然ThinkPHP的底层安全防护比之前版本要强大不少,但永远不要相信用户提交的数据,建议务必遵守下面规则: 设置public目录为唯一对外访问目录,不要把资源文件放入应用目录; 开启表单令牌验证避免数据的重复提交,能起到CSRF防御作用; 使用框架提供的请求变量获取方法(Request类param方法及input助手函数)而不是原生系统变量获取用户输入数据; 对不同的应用需求设置def
问题内容: 假设您有一个用于处理某种XML文件或配置文件的库。该库将整个文件读入内存,并提供用于编辑内容的方法。处理完内容后,可以调用将内容保存回文件。问题是如何以安全的方式执行此操作。 覆盖现有文件(开始写入原始文件)显然是不安全的。如果该方法在完成之前失败,则最终将写入一半的文件,并且您丢失了数据。 更好的选择是在某个位置写入 临时 文件,方法完成后, 将 临时文件 复制 到原始文件。 现在,
虽然可以在Java 8中序列化lambda,但强烈建议不要这样做;甚至不鼓励序列化内部类。给出的原因是lambdas可能无法在另一个JRE上正确反序列化。然而,这是否意味着有一种方法可以安全地序列化lambda? 例如,假设我定义一个类如下: 如果像这样声明了类的实例,则不应序列化它: 但如果我创建一个这样的类实例,会怎么样: 现在序列化是安全的吗?我的直觉告诉我,是的,它应该是安全的,因为没有理
问题内容: 我正在使用node.js的WSwebsocket库。目前,我正在运行ws服务器。现在,我想通过使用安全连接(即通过实施wss协议以及库支持TLS连接)来保护此连接。我进行了一些搜索,发现这很容易确保安全:wss和具有自签名证书的wss。 两者都不是很详细,第二个链接上的文章介绍了带有自签名证书的wss。我想知道的是,仅创建自签名证书并部署到我的生产环境是否就足够了?还是我需要像创建HT