Как я могу преобразовать Windows OsString в CString? - PullRequest
0 голосов
/ 26 января 2019

У меня std::ffi::OsString в Windows, но мне нужно передать std::ffi::CString в функцию FFI.Есть ли способ преобразовать OsString в CString?

. Я знаю, что в Windows OsString поддерживается буфером в кодировке WTF-8.По сути, все, что должно произойти, - это добавить символ ASCII nul и создать из него строку CString.Есть ли хороший способ сделать это?Если нет, возможно ли получить прямой доступ к этому буферу?

Вот пример кода:

extern "system" fn some_ffi(s: *mut c_char);

fn my_func(os_string: &OsString) {
    let c_string: CString = // ???

    some_ffi(c_string.as_raw())
}

1 Ответ

0 голосов
/ 26 января 2019

В Unix-подобных системах вы можете получить необработанные байты OsStr или OsString как &[u8] через std::os::unix::ffi::OsStrExt::as_bytes. Вы можете передать этот фрагмент непосредственно в CString::new.

В Windows вы не можете получить необработанные байты OsStr или OsString. Кодирование WTF-8 считается частной реализацией. Единственная гарантия состоит в том, что если строка содержит действительный Unicode, то она может быть преобразована в str или String в постоянное время, используя OsStr::to_str или OsString::into_string , Вы также можете преобразовать строку обратно в потенциально плохо сформированный UTF-16 с помощью std::os::windows::ffi::OsStrExt::encode_wide.

Мотивация отказа от прямого доступа к необработанным байтам состоит в том, что почти ни одна библиотека не ожидает строк, закодированных как WTF-8. На самом деле, некоторые библиотеки могут даже не ожидать UTF-8! (Вместо этого они могут ожидать строки, закодированные в текущей кодовой странице "ANSI" .) Если окажется, что библиотека не ожидает строки UTF-8, вам следует вместо этого преобразовать потенциально плохо сформированный UTF- 16 строк в ожидаемую кодировку с использованием WideCharToMultiByte.

...