From rawpointer to rust struct


#1

Hi Folks,

I am working a lot with FFI.

One pattern that I see very often is to get a C pointer that points to a Rust structure, make it usable by rust and then forgetting it to avoid the drop.

At the moment I just use the Box API, with something like this:

struct A {}

fn foo(p_A: *mut std::raw::c_void) {
    let a = unsafe { Box::from_raw(p_A as *mut A) };
    // ... do whatever I need to do ...
    Box::into_raw(a); 
}

This work kinda ok, but I am wondering if there is a better way to achieve the same result without using the Box API.


#2

Box::from_raw/Box::into_raw are only needed if you want to manage ownership over the memory, such as allocating/deallocating and simply transferring ownership between Rust and FFI.

In foo(), it sounds like you can simply either work with the raw pointer or turn it into a Rust reference, e.g.:

fn foo(a: *mut A) {
    let a = unsafe {&mut *a};
    // do whatever with `a`
}

#3

Thank you very much!


#4

Also let a = unsafe { a.as_ref().unwrap() } to catch NULL.


#5

Another question!

What happens if I have a complex struct that may require memory work but I use it via raw pointers?

struct A {
    v: Option<Vec<i32>>,
}

fn foo(a: *mut A) {
    let mut a = unsafe { a.as_ref().unwrap() };
    a.v = None
    // suppose that before there was a vector with some elements, 
    // does it get dropped or we leak memory? 
}

In case similar to this one how is the memory managed?


#6

The Vec will get dropped (if it was there) - raw ptr doesn’t change that.