How to return byte array from Rust function to FFI C?

If you want to return Rust allocated memory, then you’ll need to export a function to free it as well, which the C code can call. Here’s a quick example:

#[repr(C)]
struct Buffer {
    data: *mut u8,
    len: usize,
}

extern "C" fn generate_data() -> Buffer {
    let mut buf = vec![0; 512].into_boxed_slice();
    let data = buf.as_mut_ptr();
    let len = buf.len();
    std::mem::forget(buf);
    Buffer { data, len }
}

extern "C" fn free_buf(buf: Buffer) {
    let s = unsafe { std::slice::from_raw_parts_mut(buf.data, buf.len) };
    let s = s.as_mut_ptr();
    unsafe {
        Box::from_raw(s);
    }
}

You may want to consider having the Rust code take an externally allocated buffer instead, so that its (de)allocation is handled elsewhere.

As noted upthread, the important thing is to not mix up the different allocators.

6 Likes