너를 속였다
너를 속였다

Reputation: 1069

How to get raw pointer of box without consuming it?

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

Answers (1)

Peter Hall
Peter Hall

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

Related Questions