I\'m writing a safe Rust layer with which I can call functions from a C library in Rust. I\'ve generated the unsafe bindings using rust-bindgen, but I\'m getting a little co
but I do have a decent background in C
The moral equivalent of your Rust code is:
int *v = NULL;
imeGet(addr, v);
*v
This will have an error because the C code is likely going to dereference that v
to store the value in, except you've passed in a NULL, so it's more likely to go boom.
You need to create storage for the value, then provide a reference to that storage to the function:
fn ime_get(addr: u8) -> i32 {
let mut v = 0;
unsafe { imeGet(addr, &mut v) };
v
}
The solution for any pointer type uses ptr::null_mut:
unsafe {
let mut v = std::ptr::null_mut();
takes_a_pointer_pointer(addr, &mut v);
v
}
The general solution for any type uses mem::MaybeUninit:
unsafe {
let mut v = std::mem::MaybeUninit::uninit();
takes_a_value_pointer(addr, v.as_mut_ptr());
v.assume_init()
}
For completeness, you should be checking the return value:
fn ime_get(addr: u8) -> Option<i32> {
let mut v = 0;
let success = unsafe { imeGet(addr, &mut v) };
if success {
Some(v)
} else {
None
}
}
the differences between how Rust and C work with regards to passing pointers.
There really aren't any, at this level.