什么';定义指向C不透明指针的字段的Rust习惯用法是什么?

什么';定义指向C不透明指针的字段的Rust习惯用法是什么?,rust,Rust,给定一个结构: #[repr(C)] pub struct User { pub name: *const c_char, pub age: u8, pub ctx: ??, } 字段ctx将仅由C代码操作;它是指向C结构的指针UserAttr 根据,选择将被定义为不透明类型pub enum UserAttr{}。但是,我发现Rust无法复制其值,例如 Rust中定义这样一个不透明指针的正确方法是什么,这样它的值(作为指针)就可以跨方法复制?未来 介绍了外部类型的概念。

给定一个结构:

#[repr(C)]
pub struct User {
    pub name: *const c_char,
    pub age: u8,
    pub ctx: ??,
}
字段
ctx
将仅由C代码操作;它是指向C结构的指针
UserAttr

根据,选择将被定义为不透明类型
pub enum UserAttr{}
。但是,我发现Rust无法复制其值,例如

Rust中定义这样一个不透明指针的正确方法是什么,这样它的值(作为指针)就可以跨方法复制?

未来 介绍了外部类型的概念。虽然已经实施,但尚未稳定下来。一旦成功,它将成为首选的实施方式:

#![feature(extern_types)]

extern "C" {
    type Foo;
}

type FooPtr = *mut Foo;
今天 国家:

要在Rust中执行此操作,让我们创建自己的不透明类型:

#[repr(C)] pub struct Foo { private: [u8; 0] }
#[repr(C)] pub struct Bar { private: [u8; 0] }

extern "C" {
    pub fn foo(arg: *mut Foo);
    pub fn bar(arg: *mut Bar);
}
通过包含一个私有字段而不包含构造函数,我们创建了一个不透明的 无法在此模块外实例化的类型。空数组 既为零大小,又与
#[repr(C)]
兼容。但是因为我们的
Foo
Bar
类型不同,我们将在 其中两个,因此我们不能意外地将指向
Foo
的指针传递给
bar()

创建一个不透明指针,这样就没有创建此类类型的常规方法;您只能创建指向它的指针

mod ffi {
    use std::ptr;

    pub struct MyTypeFromC { _private: [u8; 0] }

    pub fn constructor() -> *mut MyTypeFromC {
        ptr::null_mut()
    }

    pub fn something(_thing: *mut MyTypeFromC) {
        println!("Doing a thing");
    }
}

use ffi::*;

struct MyRustType {
    score: u8,
    the_c_thing: *mut MyTypeFromC,
}

impl MyRustType {
    fn new() -> MyRustType {
        MyRustType {
            score: 42,
            the_c_thing: constructor(),
        }
    }

    fn something(&mut self) {
        println!("My score is {}", self.score);
        ffi::something(self.the_c_thing);
        self.score += 1;
    }
}

fn main() {
    let mut my_thing = MyRustType::new();
    my_thing.something();
}
把它分解一下:

//不透明------V~~~~~~~~~V
*mut MyTypeFromC
//^~~^----指针
因此,它是一个不透明的指针。移动struct
MyRustType
不会更改指针的值

过去
此答案和文档的先前迭代建议使用空枚举(
enum MyTypeFromC{}
)。没有变量的枚举在语义上等同于从不类型(
),这是一种不可能存在的类型。有人担心使用这样的构造可能会导致未定义的行为,因此移动到空数组被认为是更安全的。

不是“Rust无法复制其值”,只是Rust和C等语言就是这样工作的。您是否阅读了另一个问题的答案,特别是关于
Box