*const u8 and C FFI


#1

Hello,

currently I’m writing a small library that should be callable from C.
However I have a small understanding problem on how to “free” the memory afterwards.

at the moment I defined a Buffer for C like that:

pub struct Buffer {
    pub data: *const u8,
    pub len: usize,
}

The Buffer gets exported via a function like that:

#[no_mangle]
pub extern "C" fn extract_information(path: *mut c_char) -> Buffer

Do I know need a second function to clean the memory? I’ve read a lot of articles about *mut u8 however nothing about *const u8.


#2

The types *const/*mut specifically are not managed by Rust and it doesn’t know how to free them.

However, you usually cast from and to Box, which is managed and freed by Rust:

https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw

So you’d create another function free_information that uses Box::from_raw to convert a raw pointer to Box pointer (and then you don’t have to free the box — Rust will do it automatically).

For an allocated array of bytes, you’d probably want Box<[u8]> (it’s simpler than Vec, which also has capacity).

https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_boxed_slice

let slice = slice::from_raw_parts_mut(data, len);
let boxed_slice: Box<[u8]> = Box::from_raw(slice);

#3

ah well that’s what I thought already (but good to have a confirmation for that). I think what I missed is that *const u8 and *mut u8 are “basically” the same, i.e. I can just call let ptr = value as *mut u8 or let ptr = value as *const u8. (It’s impossible to call from_raw_parts_mut or from_raw onto a *const u8)


#4

Yes, you can cast them at will. foo as *mut _ is a nice shortcut.