gpt4 book ai didi

rust - 如何在 Rust 中存储对结构的 void* 引用?

转载 作者:行者123 更新时间:2023-11-29 07:58:09 24 4
gpt4 key购买 nike

我正在与一些使用标准 void* userdata 方法的 C 回调进行交互,以允许您存储对某些上下文(例如结构)的引用。如何在 void* 中存储对 Rust 结构的引用并仍然允许它四处移动?看起来 Rust 的 Action 真的是 Action ,即这段代码失败了(如预期的那样):

struct Thing {
pointer_to_self: *mut Thing,
}

fn create_thing() -> Thing {
let mut a = Thing {
pointer_to_self: std::ptr::null_mut(),
};
a.pointer_to_self = &mut a as *mut _;
a
}

fn main() {
let mut b = create_thing();

assert_eq!(&mut b as *mut _, b.pointer_to_self);
}

有解决办法吗?我可以拥有一个在移动时地址不会改变的 Rust 值吗?

最佳答案

您可以通过堆分配对象来防止值更改地址。这将花费取消引用来访问它,但它将是固定的:

struct RealThing {
// ...
}

struct Thing {
// pointer could also be a field in RealThing, but it seems to
// make more sense to leave only the actual payload there
real_thing: Box<RealThing>,
pointer_to_real: *mut RealThing,
}

fn create_thing() -> Thing {
let mut a = Thing {
real_thing: Box::new(RealThing {}),
pointer_to_real: std::ptr::null_mut(),
};
a.pointer_to_real = a.real_thing.as_mut() as *mut _;
a
}

fn main() {
let mut b = create_thing();

assert_eq!(b.real_thing.as_mut() as *mut _, b.pointer_to_real);
}

请注意,如果您尝试使用同时已被移动或复制构造的对象的地址,您将在 C++ 中遇到同样的问题。

警告:实际使用指针将导致未定义的行为,除非采取预防措施以防止存在对同一对象的多个可写引用。 UnsafeCell文档说:

In general, transmuting an &T type into an &mut T is considered undefined behavior. The compiler makes optimizations based on the knowledge that &T is not mutably aliased or mutated, and that &mut T is unique.

装箱可能更安全RefCell<RealThing> ,将不可变指针存储到盒装单元格,并将其转换回 &mut RealThing通过将指针指向 &RefCell<RealThing>并调用 borrow_mut()在引用上。如果您随后犯了错误,至少 Rust 会通过 panic 来警告您。

关于rust - 如何在 Rust 中存储对结构的 void* 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41089016/

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