【问题标题】:How do I expose a compile time generated static C string through FFI?如何通过 FFI 公开编译时生成的静态 C 字符串?
【发布时间】:2018-12-04 10:44:45
【问题描述】:

我正在尝试将版本号嵌入到库中。理想情况下,这应该是一个可以读取的静态 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 类型更合适,那么使用它就完美了。

【问题讨论】:

    标签: rust ffi


    【解决方案1】:

    通过确保静态字符串切片与 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 中的函数。

    【讨论】:

      猜你喜欢
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多