如何从Rust访问在C中声明的以0结尾的函数指针数组? [英] How do I access a zero-terminated array of function pointers declared in C from Rust?
问题描述
我有以下带有零终止函数指针数组的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
不是指向函数指针的指针,而是一个函数指针数组.在C代码中使用名称vlog_startup_routines
时,数组左值被强制为指针.这并不意味着该变量存储了一个指针!
要在Rust中最紧密地表达这一点,我们可以将vlog_startup_routines
定义为数组.问题在于我们不知道数组中有多少个元素,因为它是NULL终止的.为防止意外使用,我们将长度设置为零,并且仅通过原始指针的偏移量访问元素.
我们将 This code is compiled and linked to my Rust program using a Cargo build script. How can I call each of the function pointers in the array from Rust? A combination of the previous two answers looks nicer:
The symbol To most closely express this in Rust, we can define We use 这篇关于如何从Rust访问在C中声明的以0结尾的函数指针数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!Option<extern "C" fn()>
用于可为空的函数指针,如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
is not a pointer to a function pointer, it's an array of function pointers. When you use the name vlog_startup_routines
in C code, the array lvalue is coerced to a pointer. That doesn't mean that the variable stores a pointer! vlog_startup_routines
as an array. The problem is that we don't know how many elements are in the array because it's NULL-terminated. To prevent any accidental misuse, we set the length to zero and only access elements though offsets of the raw pointer.Option<extern "C" fn()>
for the nullable function pointer as described in the FFI chapter of The Rust Programming Language.