加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何检查从C传递的函数指针是否为非NULL

发布时间:2020-12-16 03:38:28 所属栏目:百科 来源:网络整理
导读:示例代码如下 Rust部分: #[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(i
示例代码如下

Rust部分:

#[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 %dn",value,result);

    call_c_function(0,NULL);  // Crash here

    return EXIT_SUCCESS;
}

当然call_c_function的第二次调用会崩溃.
Rust编译器不会抱怨call_c_function中的不安全代码,因为从生锈的角度来看这段代码是安全的.也不允许简单地写:

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

因为有趣的类型是fn(i32) – > i32(它不是指针).

所以我的问题是,如何保护call_c_function免受NULL指针取消引用?有没有办法检查从C传递的回调是否无效?

也许我必须改变call_c_function的定义?

解决方法

您可以使用Option< ...>表示可空函数指针.对于fn(…)类型的值具有NULL值是不正确的,因此对于这样的情况需要Option包装器.

例如,

#[no_mangle]
pub extern 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(…))类型:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读