Example code below
The Rust part:
#[no_mangle]
pub extern fn call_c_function(value: i32, fun: fn(i32) -> i32) -> i32 {
fun(value)
}
You can use Option<...>
to represent nullable function pointers. It is incorrect to have a NULL value for a value of type fn(...)
so the Option
wrapper is required for cases like this.
For example,
#[no_mangle]
pub extern "C" fn call_c_function(value: i32, fun: Option<fn(i32) -> i32>) -> i32 {
if let Some(f) = fun {
f(value)
}
}
However, there's one extra point: fun
is a C function, but the type fn(...)
is a Rust function. They're not directly compatible (e.g. their calling conventions differ). One needs to use the extern "C" fn(...)
(a.k.a. extern fn(...)
) type when interacting with C function pointers:
#[no_mangle]
pub extern "C" fn call_c_function(value: i32, fun: Option<extern "C" fn(i32) -> i32>) -> i32 {
if let Some(f) = fun {
f(value)
}
}
You can compare a pointer that has been generated by unsafe code against std::ptr::null()
e.g.
let pw = libc::getpwnam(username.as_ptr() as *const i8);
if std::ptr::null() != pw ...
null()
on Linux is 0 as *const T
I'm not sure if that is universal.