如何将Windows OsString转换为CString?

ddu*_*ney 2 ffi rust

std::ffi::OsString在Windows上有一个,但我需要传递一个std::ffi::CStringFFI函数.有没有办法把它转换OsStringCString

我知道在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())
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*gné 6

在类Unix系统上,您可以获取OsStrOsString作为&[u8]通道的原始字节std::os::unix::ffi::OsStrExt::as_bytes.您可以直接将该切片传递给CString::new.

在Windows上,您无法获取OsStr或的原始字节OsString.WTF-8编码被认为是私有实现细节.唯一的保证是,如果字符串包含有效的Unicode,则可以使用或将其转换为a strString在恒定时间内.您还可以将字符串转换回可能格式错误的UTF-16 .OsStr::to_strOsString::into_stringstd::os::windows::ffi::OsStrExt::encode_wide

不直接访问原始字节的动机是几乎没有库期望字符串编码为WTF-8.事实上,有些图书馆甚至可能不会期待UTF-8!(他们可能会期望在当前"ANSI"代码页中编码的字符串.)如果事实证明该库不期望UTF-8字符串,则应该将可能格式错误的UTF-16字符串转换为预期的编码使用WideCharToMultiByte.