Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Rust FFI时,如何初始化不透明的C结构?_Rust_Ffi - Fatal编程技术网

使用Rust FFI时,如何初始化不透明的C结构?

使用Rust FFI时,如何初始化不透明的C结构?,rust,ffi,Rust,Ffi,下面是我在C代码中要做的事情: #包括 int main(){ 一些库结构; 一些_lib_func(&x); } 我如何利用图书馆?以下是到目前为止我得到的信息: extern crate libc; // 0.2.51 struct some_lib_struct_t; #[link(name = "some_lib")] extern "C" { fn some_lib_func(x: *mut some_lib_struct_t); } fn main() { l

下面是我在C代码中要做的事情:

#包括
int main(){
一些库结构;
一些_lib_func(&x);
}
我如何利用图书馆?以下是到目前为止我得到的信息:

extern crate libc; // 0.2.51

struct some_lib_struct_t;

#[link(name = "some_lib")]
extern "C" {
    fn some_lib_func(x: *mut some_lib_struct_t);
}

fn main() {
    let mut x: some_lib_struct_t;
    unsafe {
        some_lib_func(&mut x);
    }
}
编译时出现错误:

错误[E0381]:借用可能未初始化的变量:`x`
-->src/main.rs:13:23
|
13 |一些自由函数(&mut x);
|^^^^^^使用可能未初始化的`x`

最安全的答案是自己初始化结构:

let mut x: some_lib_struct_t = some_lib_struct_t;
unsafe {
    some_lib_func(&mut x);
}
与C代码最接近的模拟是使用

在生锈1.36之前,您可以使用:

必须确保
某些_lib_func
完全初始化结构的所有成员,否则不安全性将泄漏到
不安全
块之外

说到“结构的成员”,我几乎可以保证你的代码不会做你想做的事情。您已将
某些库结构
定义为大小为零。这意味着不会为它分配堆栈空间,对它的引用也不会是您的C代码所期望的

您需要在Rust中镜像C结构的定义,以便可以分配适当的大小、填充和对齐方式。通常,这意味着使用
repr(C)

很多时候,C库总是返回指向不透明类型的指针,从而避免暴露其内部结构表示:

阅读后,我仔细查看了库的标题。正如他们所说,
some_lib_struct
只是指向
real_lib_struct
的指针的类型定义。我做了以下修改:

extern crate libc;

struct actual_lib_struct_t;
type some_lib_type_t = *mut actual_lib_struct_t;

#[link(name="some_lib")]
extern {
    fn some_lib_func(x: *mut some_lib_type_t);
}

fn main() {
    let mut x: some_lib_type_t;
    unsafe {
        x = std::mem::uninitialized();
        some_lib_func(&mut x);
    }
}

而且它有效!然而,我确实得到了警告:代码>在外部模块中找到了零大小结构,考虑将一个成员添加到这个结构中,{ [警告(不正确的cType)]默认为 .< /P> < p>从文档中获得:

自1.39.0以来已弃用:改用

新的解决方案如下所示:

使用std::mem::maybeunit;
让实例=不安全{
设mut x:maybeunit=maybeunit::uninit();
一些函数(x.as_mut_ptr());
x、 假设_init()
}

我使用mem::uninitialized()实现了它。但是我从编译器那里得到一个警告。我用更多信息更新了这个问题。@EFTH我已经解决了这个问题。请参阅我的答案中有关“零尺寸”的部分。如果您有一个不透明的指针,那么请查看3个链接问题。请注意,自1.39.0以来,
std::mem::uninitialized
已被弃用:请改用
mem::maybeuniit
unsafe {
    let mut x: some_lib_struct_t = std::mem::uninitialized();
    some_lib_func(&mut x);
}
extern crate libc;

struct actual_lib_struct_t;
type some_lib_type_t = *mut actual_lib_struct_t;

#[link(name="some_lib")]
extern {
    fn some_lib_func(x: *mut some_lib_type_t);
}

fn main() {
    let mut x: some_lib_type_t;
    unsafe {
        x = std::mem::uninitialized();
        some_lib_func(&mut x);
    }
}