The documentationはあなたに嘘をついていません。
ルーストにこれを行うには、のはenum
と私たち自身の不透明タイプを作成してみましょう:
pub enum Foo {}
pub enum Bar {}
extern "C" {
pub fn foo(arg: *mut Foo);
pub fn bar(arg: *mut Bar);
}
なし変種でenum
を使用することにより、我々は作成私たちが である不透明な型は、それが変種を持たないので、インスタンス化できません。しかし、Foo
とBar
の型が異なるので、2つの型の間で型の安全性が確保されるので、 Foo
へのポインタを誤ってbar()
に渡すことはできません。
通常、このようなタイプを作成する通常の方法はないため、不透明なポインタはenum Foo {}
です。あなたはそれへのポインタを作成することしかできません。
mod ffi {
use std::ptr;
pub enum MyTypeFromC {}
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();
}
少しそれを破壊:
// opaque -----V~~~~~~~~~V
*mut MyTypeFromC
// ^~~^ ------------ pointer
は、したがって、不透明なポインタです。構造体MyRustType
を移動しても、ポインタの値は変更されません。
「錆はその価値をコピーすることができません」というわけではありません。錆やCなどの言語がどのように機能するかだけです。あなたは他の質問の答え、特に 'Box'について読んだことがありますか? – mcarton