gpt4 book ai didi

rust - 你能以某种方式将不安全的指针转换为 rust 中的拥有指针吗?

转载 作者:行者123 更新时间:2023-11-29 08:00:43 25 4
gpt4 key购买 nike

我意识到这是一件难以理解的事情,但有时能够通过 ffi 将值存储在 c 库中,然后从 c 回调到 rust 函数会有所帮助。

在这些情况下,我发现我想要拥有一个存储为 mut * c_void 的自有指针。

您可以使用此方法与 forget() 一起将值存储在 C 中,并且您可以相对轻松地将其恢复为另一侧的 mut * T,但能够在这种情况下,移出不安全指针并返回“安全” rust 空间。

但是,编译器总是会提示将引用移出 & 指针。

是否有一种特殊的方法可以将 &T 或 *T 不安全地转换为 ~T?

这可能有点不清楚,所以这是一个具体的例子:

extern crate libc;

use libc::c_void;
use std::ops::Drop;
use std::intrinsics::forget;

struct Foo { x: int }

impl Drop for Foo {
fn drop(&mut self) {
println!("We discarded our foo thanks!");
}
}

fn main() {
let mut x = ~Foo { x: 10 };

let mut y = & mut *x as * mut Foo;
println!("Address Y: {:x}", y as uint);

let mut z = y as * mut c_void;
println!("Address Z: {:x}", z as uint);

// Forget x so we don't worry about it
unsafe { forget(x); }

// This would normally happen inside the ffi callback where
// the ffi code discards the void * it was holding and returns it.
unsafe {
let mut res_z = z as * mut Foo;
println!("Ressurected Z: {:x}", z as uint);

let mut res_y = & mut (*res_z);
println!("Ressurected Y: {:x}", y as uint);

let mut res_x:~Foo = ~(*res_y);
}
}

最后一行无法编译,因为:

test.rs:34:28: 34:34 error: cannot move out of dereference of `&mut`-pointer
test.rs:34 let mut res_x:~Foo = ~(*res_y);

如果删除该行,则永远不会调用析构函数;我正在寻找一种方法将该内存块移回“安全”使用rust 区,并在 block 作用域结束时正确收集它。

编辑:我怀疑 swap() 是执行此操作的方法,但在不泄漏的情况下正确执行它的确切语义对我来说仍然有点模糊。例如在 https://gist.github.com/shadowmint/11361488 ~Foo 泄漏;为被遗忘的 ~Foo 调用析构函数,但我们泄漏了在 tmp 中创建的本地 ~Foo。 :/

最佳答案

您的错误发生是因为 ~ 是用于装箱的运算符,而不是指针。您不能将拥有的指针“带入”某物,因为创建拥有的指针始终意味着在堆上进行分配。因此您的错误 - ~ 试图将值移出 &mut,这是不允许的。

我相信对于这种真的不安全的事情,你需要cast::transmute():

use std::cast;

// ...

let mut res_x: ~Foo = cast::transmute(res_y);

经过此修改后的代码可以正常工作,它会打印 We discarded our foo thanks!。但是,您应该真的小心cast::transmute(),因为它完全不检查(除了转换类型的内存大小)并且允许您强制转换所有内容对一切。

关于rust - 你能以某种方式将不安全的指针转换为 rust 中的拥有指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23331808/

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