gpt4 book ai didi

rust - 将数据和指向该数据的可变指针存储在结构中是否安全?

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

让我们考虑一个围绕 C 库的 Rust 包装器库。此 C 库定义了一个结构并将其用作整个 API 中的可变指针。

Rust 包装器定义了以下结构,其中 ptr 指向 data

struct Wrapper {
data: struct_from_c_t,
ptr: *mut struct_from_c_t,
}

如果此指针的所有使用都在 Wrapper 结构的生命周期内进行,那么在不安全代码中使用此指针时我还会遇到哪些其他潜在问题?

在这个结构中取消引用和使用这个指针总是安全的吗?

对于详细上下文,目标是能够使用此指针从非可变借用 Wrapper 的函数中调用 FFI 函数。

最佳答案

这通常是一个坏主意,而且非常容易出错。

首先,阅读Why can't I store a value and a reference to that value in the same struct?有关为什么安全 Rust 在编译时阻止此构造的深入解释。

TL;DR,如果您曾经移动Wrapper 结构,指针将无效。取消引用它会导致未定义的行为(一件坏事)。

如果您可以确保:

  1. Wrapper 永远不会移动。
  2. ptr 会在您每次移动结构时更新。

然后指针将是有效的并且可以安全地取消引用(假设支持所有其他关于不安全代码的警告)。


更糟糕的是,没有理由将指针放在第一位;您可以在需要时获取对值的引用并将其转换为指针:

extern "C" {
fn ffi_fn(data: *mut struct_from_c_t);
}

struct Wrapper {
data: struct_from_c_t,
}

impl Wrapper {
fn do_thing(&mut self) {
unsafe { ffi_fn(&mut self.data) }
}
}

from functions borrowing Wrapper non-mutably

在没有上下文的情况下,这似乎是一个可疑的决定,但 Rust 具有用于内部可变性的工具:

use std::cell::RefCell;

struct Wrapper {
data: RefCell<struct_from_c_t>,
}

impl Wrapper {
fn do_thing(&self) {
unsafe { ffi_fn(&mut *self.data.borrow_mut()) }
}
}

关于rust - 将数据和指向该数据的可变指针存储在结构中是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53263849/

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