Как открыть статическую C-строку, сгенерированную во время компиляции, через FFI? - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь встроить номер версии в библиотеку.В идеале это должна быть статическая строка C, которая может быть прочитана и не нуждается в дополнительном выделении для чтения номера версии.

Со стороны Rust я использую vergen для генерации информации о версиях, напримерэто:

pub static VERSION: &str = env!("VERGEN_SEMVER");

, и я хотел бы в конечном итоге что-то вроде

#[no_mangle]
pub static VERSION_C: *const u8 = ... ;

Кажется, есть способ достичь этого с помощью строковых литералов , ноЯ не нашел способ сделать это с помощью строк времени компиляции.Создание нового CString, по-видимому, выходит за рамки текущих возможностей статических переменных и имеет тенденцию заканчиваться ошибкой E0015 .

Функция, возвращающая указатель, подобный этому, будет приемлемой, если только она не выделяет новую память.

#[no_mangle]
pub extern "C" fn get_version() -> *const u8 {
    // ...
}

Окончательный тип переменной (или возвращаемый тип функции)не должен быть основан на u8, но должен быть переведен через cbindgen.Если какой-то другой тип FFI более уместен, использовать его вполне нормально.

1 Ответ

0 голосов
/ 04 декабря 2018

Обеспечивая совместимость статического фрагмента строки со строкой в ​​стиле C (например, он заканчивается нулевым завершающим байтом \0), мы можем безопасно извлечь указатель на начало фрагмента и передать его черезthe border.

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.

...