这里的问题是,vlog_startup_routines
不是一个指针。如果你声明它是一个指针;它是一个数组。该符号解析为数组第一项的地址。在C中,如果您有:
int i = 7;
int a[1] = { 8 };
int *p = &i;
在接头水平
然后,符号i
是包含值7的位置的地址,a
是也含有一个整数值的位置的(8地址),并且p
是包含指向整数的指针的位置的地址。另一种说法是,链接符号总是变量的地址。
如果你将它声明为:
// Or whatever argument types
type VlogStartupRoutine = extern "C" fn();
extern "C" {
static vlog_startup_routines: VlogStartupRoutine;
}
你说vlog_startup_routines
是包含一个函数指针的变量,更象C void *vlog_startup_routines
。
unsafe {
println!("{:p}", vlog_startup_routines);
println!("{:p}", hello_register as *const());
}
它提领走存储在地址vlog_startup_routines
,这的确是第一个指针的值。
正确的(几乎)代码:
type VlogStartupRoutine = Option<extern "C" fn()>;
#[link(name = "funcref")]
extern "C" {
static vlog_startup_routines: [VlogStartupRoutine;10];
fn hello_register();
}
fn main() {
unsafe {
println!("{:p}", vlog_startup_routines.as_ptr());
println!("{:p}", hello_register as *const());
}
unsafe {
let routine = vlog_startup_routines[0].unwrap();
println!("Calling startup");
routine();
assert!(vlog_startup_routines[1].is_none());
}
}
请注意,我用Option<extern "C" fn()>
为null的函数指针作为described here。
这种输出,对我来说:
0x7efc27d37030
0x7efc27b366f0
Calling startup
hello_register called
我之所以说“几乎”是,我不知道怎么说这是一个未知大小的数组。:-)
还有我读到另一个问题完全向后想后我对工作反正答案... – Shepmaster