Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
355 views
in Technique[技术] by (71.8m points)

How to hold Rust objects in Rust code created through C++?

I want to create instances of Rust structs through C++. C++ has the main function and the Rust code is used as a library.

To achieve that, I need a way to store the instances in a list of some kind and return the index of the list to C++ so it works like a pointer to a Rust struct.

Rust does not support static members, so I cannot create a static rust_instances: std::vec::Vec = std::vec::Vec::new() to hold the Rust structures.

What would be the best option here?

I've searched and found some workarounds that simulate a static element, but I'd like to know if there's a better way to solve this problem.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

To achieve that, we need a way to store the instances into a list of some kind, and return the index of the list to C++, so it works like a pointer to a Rust struct.

I can't see why this would be the case. You don't need a static list to return pointers from Rust. Simply allocate a Box in Rust and return it to the C++ code – a Box<T> with T: Sized has the same memory layout as a C pointer.

As explained in the linked documentation, your code can simply look like this:

// C++ header

// Returns ownership to the caller
extern "C" void *foo_new();

// Borrows mutably. The pointee cannot be changed by a different thread
// during the runtime of the function. The argument must be a pointer
// allocated with foo_new().
extern "C" void foo_transmogrify(void *);

// Takes ownership from the caller; no-op when invoked with NULL
extern "C" void foo_delete(void *);
#[repr(C)]
pub struct Foo {
    glonk: bool,
}

#[no_mangle]
pub extern "C" fn foo_new() -> Box<Foo> {
    Box::new(Foo { glonk: false })
}

#[no_mangle]
pub extern "C" fn foo_transmogrify(foo: &mut Foo) {
    foo.glonk = true;
}

#[no_mangle]
pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}

Note that the deallocation function can simply be empty. It will take ownership of the Box and implicitly drops it at the end of the function body.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...