rust - 如何从 Rust 访问用 C 声明的函数指针的零终止数组?

标签 rust function-pointers ffi

我有以下带有零终止函数指针数组的 C 代码:

#include <stdio.h>

void hello_register(void) {
  printf("hello_register called\n");
}

void (*vlog_startup_routines[])() = {
    hello_register,
    0
};

此代码使用 Cargo 构建脚本编译并链接到我的 Rust 程序。我如何从 Rust 调用数组中的每个函数指针?

最佳答案

前两个答案的组合看起来更好:

extern crate libc;

type VlogStartupRoutine = Option<extern "C" fn()>;

extern "C" {
    // This array is NULL-terminated; set the length to zero to
    // prevent any uncontrolled access.
    static vlog_startup_routines: [VlogStartupRoutine; 0];
}

fn main() {
    unsafe {
        let routines = vlog_startup_routines.as_ptr();

        for i in 0.. {
            match *routines.offset(i) {
                Some(routine) => {
                    println!("Calling startup routine #{}", i);
                    routine();
                }
                None => break,
            }
        }
    }
}

符号vlog_startup_routines不是指向函数指针的指针,它是一个函数指针数组。当您使用名称 vlog_startup_routines在 C 代码中,数组左值被强制转换为指针。这并不意味着变量存储指针!

为了在 Rust 中最准确地表达这一点,我们可以定义 vlog_startup_routines作为一个数组。问题是我们不知道数组中有多少元素,因为它以 NULL 结尾。为防止任何意外误用,我们将长度设置为零,并且仅通过原始指针的偏移量访问元素。

我们使用 Option<extern "C" fn()>对于可空函数指针,如 FFI chapter of The Rust Programming Language 中所述.

关于rust - 如何从 Rust 访问用 C 声明的函数指针的零终止数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40567119/

相关文章:

multidimensional-array - ndarray : Is there an effective way to swap 2 row/cols/etc.在不同的数组?

rust - 为什么标识符不能以数字开头?

performance - Rust 在解析文件时比 Python 慢

rust - 如何在 Rust 中共享功能?

c++ - 传递成员函数指针

rust - 如何将 Vec<T> 转换为 C 语言友好的 *mut T?

Haskell - FFI 和指针

c++ - 成员函数回调

c++ - 通过参数传递 lambda(无函数类型模板)

go - 如何使用 slice 作为参数从 Go 调用 Rust 函数?