Pointer c_void or u8

I’m working on FFI, there is a C function with signature:

bool write_data(int fd, const void *data, unsigned int len);

which copies len bytes from data to the descriptor fd. While bindgen generates the following

pub fn write_data(fd: i32, data: *const c_void, len: u32) -> bool;

I wonder if it is safe to use the below signature instead

pub fn write_data(fd: i32, data: *u8, len: u32) -> bool;

Many thanks for any help.

I presume that as long as the size of each of the parameters lines up, it’s safe, even if you make an assumption about the actual type under the pointer.

On another note, your second rust signature is invalid, it needs to be either *const T or *mut T.

2 Likes

@OptimisticPeach Thank you, sorry for *u8, it is *const u8 instead.

C is a very weird wonderful language.

I’m not entirely sure if this is safe because of the alignment of *u8 and *void. Better leave it like it is. Rust can do the conversion for you.

use std::ffi::c_void;

extern "C" {
    fn foo(_: *mut c_void);
}

fn main() {
    let mut a: u8= 8;
    let b = &mut a;
    unsafe { foo(b as *mut u8 as _) }
}
2 Likes