我正在尝试将版本号嵌入到库中。理想情况下,这应该是一个可以读取的静态C字符串,并且不需要任何额外的分配即可读取版本号。
在Rust方面,我正在使用vergen
生成如下版本信息:
pub static VERSION: &str = env!("VERGEN_SEMVER");
最后我想得到类似
#[no_mangle]
pub static VERSION_C: *const u8 = ... ;
似乎有一种使用string literals来实现这一目标的方法,但是我还没有找到一种使用编译时间字符串来实现这一目标的方法。创建新的CString
似乎超出了静态变量的当前功能,并且往往以error E0015结尾。
这样的返回指针的函数是可以接受的,只要它不分配新的内存即可。
#[no_mangle]
pub extern "C" fn get_version() -> *const u8 {
// ...
}
变量的最终类型(或函数的返回类型)不必基于u8
,但可以通过cbindgen
进行翻译。如果其他一些FFI类型更合适,则使用它就可以了。
答案 0 :(得分:6)
通过确保静态字符串切片与C样式字符串兼容(例如,它以空终止符字节\0
结尾),我们可以安全地获取指向切片开头的指针并传递跨越边界。
pub static VERSION: &str = concat!(env!("VERGEN_SEMVER"), "\0");
#[no_mangle]
pub extern "C" fn get_version() -> *const c_char {
VER.as_ptr() as *const c_char
}
这里是Playground中的一个示例,其中我使用包的版本作为环境变量来获取并在Rust中调用了函数。