Editor's note: This code example is from a version of Rust prior to 1.0 and is not valid Rust 1.0 code, but the answers still contain valuable information.
我想将字符串文字传递给 Windows API。许多 Windows 函数使用 UTF-16 作为字符串编码,而 Rust 的原生字符串是 UTF-8。
我知道 Rust 有 utf16_units()生成 UTF-16 字符迭代器,但我不知道如何使用该函数生成最后一个字符为零的 UTF-16 字符串。
我正在像这样生成 UTF-16 字符串,但我确信有更好的方法来生成它:
extern "system" {
pub fn MessageBoxW(hWnd: int, lpText: *const u16, lpCaption: *const u16, uType: uint) -> int;
}
pub fn main() {
let s1 = [
'H' as u16, 'e' as u16, 'l' as u16, 'l' as u16, 'o' as u16, 0 as u16,
];
unsafe {
MessageBoxW(0, s1.as_ptr(), 0 as *const u16, 0);
}
}
最佳答案
使用rust 1.8+
str::encode_utf16
是 UTF-16 值的稳定迭代器。
你只需要使用 collect()
在该迭代器上构建 Vec<u16>
然后 push(0)
在那个向量上:
pub fn main() {
let s = "Hello";
let mut v: Vec<u16> = s.encode_utf16().collect();
v.push(0);
}
使用rust 1.0+
str::utf16_units()
/str::encode_utf16
不稳定。另一种方法是切换到 nightly(如果您正在编写程序而不是库,这是一个可行的选择)或使用像 encoding 这样的外部 crate 。 :
extern crate encoding;
use std::slice;
use encoding::all::UTF_16LE;
use encoding::{Encoding, EncoderTrap};
fn main() {
let s = "Hello";
let mut v: Vec<u8> = UTF_16LE.encode(s, EncoderTrap::Strict).unwrap();
v.push(0); v.push(0);
let s: &[u16] = unsafe { slice::from_raw_parts(v.as_ptr() as *const _, v.len()/2) };
println!("{:?}", s);
}
(或者如果你想要一个 from_raw_parts_mut
,你可以使用 &mut [u16]
)。
但是,在这个特定示例中,您必须小心字节顺序,因为 UTF_16LE
encoding 给你一个表示 u16
的字节向量是小端字节顺序,而 from_raw_parts
技巧允许您将字节向量“查看”为 u16
的一部分是您平台的字节顺序,也可能是大端。使用像 byteorder
这样的 crate 如果您想要完全的可移植性,这里可能会有所帮助。
This在 Reddit 上的讨论也可能有帮助。
关于string - 如何将 Rust 字符串转换为 UTF-16?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25197315/