rust - How to check if function pointer passed from C is non-NULL -


example code below

the rust part:

#[no_mangle] pub extern fn call_c_function(value: i32, fun: fn(i32) -> i32) -> i32 {     fun(value) } 

and c part:

int32_t call_c_function(int32_t value, int32_t (*fun)(int32_t));  int32_t triple(int32_t x) {     return x*3; }  int main(int argc, char *argv[]) {     int32_t value = 3;     int32_t result = call_c_function(value, triple);      printf("%d tripled %d\n", value, result);      call_c_function(0, null);  // crash here      return exit_success; } 

of course second call of call_c_function crash. rust compiler not complain unsafe code inside call_c_function, because rust point of view code safe. it's not allowed write:

if !fun.is_null() {     fun(value) } 

because fun type fn(i32) -> i32 (it's not pointer).

so question is, how can protect call_c_function against null pointer dereference? there way check if callback passed c not valid?

maybe have change call_c_function definition?

you can use option<...> represent nullable function pointers. incorrect have null value value of type fn(...) option wrapper required cases this.

for example,

#[no_mangle] pub extern fn call_c_function(value: i32, fun: option<fn(i32) -> i32>) -> i32 {     if let some(f) = fun { f(value) } } 

however, there's on point: fun c function, type fn(...) rust function. they're not directly compatible (e.g. calling conventions differ), 1 needs using extern "c" fn(...) (aka extern fn(...)) type when interacting c function pointers:

#[no_mangle] pub extern fn call_c_function(value: i32, fun: option<extern fn(i32) -> i32>) -> i32 {     if let some(f) = fun { f(value) } } 

Comments