Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get raw pointer of box without consuming it?

Tags:

pointers

rust

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.

like image 980
너를 속였다 Avatar asked Mar 17 '21 13:03

너를 속였다


People also ask

Is Box A pointer in Rust?

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.

How do you dereference a pointer in Rust?

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.

Is a raw pointer try Dereferencing it?

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.


Video Answer


1 Answers

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:

  • https://doc.rust-lang.org/std/primitive.pointer.html#common-ways-to-create-raw-pointers
like image 179
Peter Hall Avatar answered Nov 07 '22 18:11

Peter Hall