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.
Because a Box<T> is a pointer, Rust always knows how much space a Box<T> needs: a pointer's size doesn't change based on the amount of data it's pointing to.
To do this we need to dereference the memory address with the unary dereferencing operator (*). The dereference operator is also known as the indirection operator. Simply put, the dereferencing operator allows us to get the value stored in the memory address of a pointer.
Raw pointer are more complicated. Raw pointer arithmetic and casts are "safe", but dereferencing them is not. We can convert raw pointers back to shared and mutable references, and then use them; this will certainly imply the usual reference semantics, and the compiler can optimize accordingly.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With