在 Rust 中创建一个 c_void 指针

Creating a c_void pointer in Rust

我有一个输入类型为 ptr::NonNull<c_void> 的函数。通常此输入由 C 代码提供。合法输入的类型为:&(int){5}

但是,我需要在 Rust 中创建一些输入。所以我做了以下事情:

let i = 5;
let data = &i as *const u32;
ptr::NonNull::new_unchecked(data as *mut _)

如果来自 C 代码的合法输入,将执行以下块:

ptr::NonNull::new_unchecked(x.data as *mut _)

其中 x.data 来自一个结构,其中 x 是类型 X:

#[repr(C)]
pub struct X {
    data: *const c_void,
}

作为参考,代码看起来像这样:

if x.data.is_null() {
    let i = 5;
    let data = &i as *const u32;
    ptr::NonNull::new_unchecked(data as *mut _)
} else {
    // x.data is specified in C code through FFI as &(int){5}
    ptr::NonNull::new_unchecked(x.data as *mut _)
}

但是,当我稍后尝试取消引用该值时,对于 else 分支,我得到了预期的 5。但是对于 if 分支,我得到了一个很大的垃圾值。我假设它与我在 Rust 中创建原始指针的方式有关。

在您的 if 分支中,您正在创建一个局部范围的变量 i,获取指向它的指针(引用)并将该引用传递给 new_unchecked,这不会复制您的数据,它只是封装了您随后传递到范围之外的指针。

稍后在程序中您尝试访问不再在范围内的数据,因此您得到未指定的数据。

尝试在 Box and use into_raw() 中定义数据以获得您的指针

编辑: 实际上,这样的事情可能会更好:

let val = if x.data.is_null() {
    5
} else {
    *x.data
};
let data = &val as *const u32;
ptr::NonNull::new_unchecked(data as *mut _)

从封闭块中取出分配。