我想要的东西:让我从我希望工作的方式开始,我将解释为什么我想进一步降低其背景。
假设我有一些功能:
extern "C" fn some_function() -> c_int {
//Do stuff
}
现在,因为我与一个将编译后的代码作为共享库加载的C程序集成在一起,所以我必须提供一个特定的函数来告诉该程序在哪里可以找到我的函数,如下所示:
#[repr(C)]
pub struct SOME_STRUCT {
pub key: *const c_char,
pub function: extern "C" fn() -> c_int,
}
pub struct SomeStruct {
pub key: ffi::CString,
pub function: extern "C" fn() -> c_int,
}
impl SomeStruct {
pub fn new(key: &str, function: extern "C" fn() -> c_int) -> Metric {
SomeStruct {
key: ffi::CString::new(key).unwrap(),
function: function,
}
}
pub fn to_c_variant(&self) -> SOME_STRUCT {
SOME_STRUCT {
key: self.key.as_ptr(),
function: self.function
}
}
}
#[no_mangle]
pub extern "C" fn some_api_function() -> *const SOME_STRUCT {
let some_struct = vec![
boxed::Box::new(SomeStruct::new("some.key", some_function)),
];
let items = some_struct
.iter()
.map(|x| x.to_c_variant())
.collect::<Vec<_>>();
mem::forget(some_struct);
items
}
现在,我不仅拥有一个功能,而且还有很多我需要以这种方式注册。而且因为我是一名程序员并且有点懒惰,所以我想知道是否有一种方法可以执行以下操作:
#[register(key=some.key)]
extern "C" fn some_function() -> c_int {
//Do stuff
}
#[register(key=some.other.key)]
extern "C" fn some_other_function() -> c_int {
//Do stuff
}
,然后该注释会自动生成如下代码:
#[no_mangle]
pub extern "C" fn some_api_function() -> *const SOME_STRUCT {
let some_struct = vec![
boxed::Box::new(SomeStruct::new("some.key", some_function)),
boxed::Box::new(SomeStruct::new("some.other.key", some_other_function)),
];
let items = some_struct
.iter()
.map(|x| x.to_c_variant())
.collect::<Vec<_>>();
mem::forget(some_struct);
items
}
这可能会导致生锈吗?
为什么要这么做:背景是我要写一个loadable module for Zabbix的锈迹。为此,我从本周开始学习防锈,到目前为止到目前为止还过得很愉快。
有人甚至writing a zabbix loadable module in rust写了一篇很棒的教程,详细说明了如何做到这一点。
现在,因为我喜欢改进某些东西,所以,如果能够以某种方式编写防锈板条箱使在rust中编写zabbix模块变得超级容易,那真是太棒了。使用该板条箱应该只需要编写一些不错的安全rust函数,并告诉编译器以某种方式将其放入将所有函数注册到zabbix的函数中即可。