如何将Windows OsString转换为CString?

时间:2019-01-26 00:01:44

标签: rust ffi

我在Windows上有一个std::ffi::OsString,但是我需要将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 :(得分:5)

在类似Unix的系统上,您可以通过std::os::unix::ffi::OsStrExt::as_bytesOsStr的形式获取OsString&[u8]的原始字节。您可以将该切片直接传递到CString::new

在Windows上,您 无法获得OsStrOsString的原始字节。 WTF-8编码被视为私有实现细节。唯一的保证是,如果字符串包含有效的Unicode,则可以使用OsStr::to_strOsString::into_string在恒定时间内将其转换为strString。您还可以使用std::os::windows::ffi::OsStrExt::encode_wide将字符串转换回可能格式不正确的UTF-16。

不直接访问原始字节的动机是几乎没有库期望将字符串编码为WTF-8。实际上,某些库甚至可能都不希望使用UTF-8! (他们可能希望使用current "ANSI" code page中编码的字符串。)如果事实证明该库不希望使用UTF-8字符串,则应使用以下命令将可能格式不正确的UTF-16字符串转换为预期的编码WideCharToMultiByte