Reputation: 1069
I need to pass a raw pointer to a struct to C++ and then still want to use that box afterwards.
I found the into_raw function but it eats the box and I can't use that box any more in Rust. Is there a way to get a *const T
? I could get away with const_cast
on C++ side.
This is what I'm trying to do:
let handle_ptr = Box::<Handle>::into_raw(handle);
std::thread::spawn(move || {
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
rt.block_on( handle.run() );
});
return handle_ptr
I know that this is unsafe but I don't know any other way to allow C++ code running on other thread to call a thread-safe method of a Rust object.
Upvotes: 13
Views: 12552
Reputation: 58735
You can dereference the box and cast the reference to its contents as a raw pointer:
let handle_ptr: *const Handle = &*handle;
Or:
let handle_ptr = &*handle as *const Handle;
Note that you haven't had to use unsafe
yet. You'll need to use unsafe
to dereference this pointer, including passing it to your C++ function. When you use unsafe
the compiler can't help you, and it's up to you to ensure that Undefined Behaviour isn't triggered, which includes checking safe code that affects memory that's accessed in unsafe code.
In this case, your C++ function may use the pointer after the box is dropped (use after free). It's therefore up to you to make sure that this cannot happen.
See examples in the documentation for raw pointers:
Upvotes: 14