I am trying to embed a version number into a library. Ideally, this should be a static C string that can be read and doesn't need any additional allocation for reading the version number.
On the Rust side, I am using vergen
to generate the versioning information like this:
pub static VERSION: &str = env!("VERGEN_SEMVER");
and I would like to end up with something like
#[no_mangle]
pub static VERSION_C: *const u8 = ... ;
There seems to be a way to achieve this using string literals, but I haven't found a way to do this with compile time strings. Creating a new CString
seems to be beyond the current capabilities of static variables and tends to end with an error E0015.
A function returning the pointer like this would be acceptable, as long as it does not allocate new memory.
#[no_mangle]
pub extern "C" fn get_version() -> *const u8 {
// ...
}
The final type of the variable (or return type of the function) doesn't have to be based on u8
, but should be translatable through cbindgen
. If some other FFI type is more appropriate, using that is perfectly fine.
By ensuring that the static string slice is compatible with a C-style string (as in, it ends with the null terminator byte \0
), we can safely fetch a pointer to the beginning of the slice and pass that across the boundary.
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
}
Here's an example in the Playground, where I used the package's version as the environment variable to fetch and called the function in Rust.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With