如何检查从C传递的函数指针是否为非NULL [英] How to check if function pointer passed from C is non-NULL
问题描述
下面的示例代码
锈部分:
#[no_mangle]
pub extern fn call_c_function(value: i32, fun: fn(i32) -> i32) -> i32 {
fun(value)
}
还有C部分:
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 is %d\n", value, result);
call_c_function(0, NULL); // Crash here
return EXIT_SUCCESS;
}
当然,call_c_function
的第二次调用将崩溃.
Rust编译器不会抱怨call_c_function
内部的不安全代码,因为从rust的角度来看,该代码是安全的.另外,也不能简单地写:
Of course second call of call_c_function
will crash.
Rust compiler will not complain about unsafe code inside call_c_function
, because from rust point of view this code is safe. Also it's not allowed to simply write:
if !fun.is_null() {
fun(value)
}
因为fun
类型是fn(i32) -> i32
(它不是指针).
because fun
type is fn(i32) -> i32
(it's not a pointer).
所以我的问题是,如何保护call_c_function
防止NULL指针取消引用?有什么方法可以检查从C传递的回调是否无效?
So my question is, how I can protect call_c_function
against NULL pointer dereference? Is there any way to check if callback passed from C is not valid?
也许我必须更改call_c_function
定义?
推荐答案
您可以使用Option<...>
表示可为空的函数指针.对于类型为fn(...)
的值具有NULL值是不正确的,因此在这种情况下需要使用Option
包装器.
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.
例如,
#[no_mangle]
pub extern "C" fn call_c_function(value: i32, fun: Option<fn(i32) -> i32>) -> i32 {
if let Some(f) = fun {
f(value)
}
}
但是,还有一个要点:fun
是C函数,而类型fn(...)
是Rust函数.它们不直接兼容(例如,它们的调用约定不同).与C函数指针进行交互时,需要使用extern "C" fn(...)
(也称为extern fn(...)
)类型:
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)
}
}
这篇关于如何检查从C传递的函数指针是否为非NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!