string - 如何将 Rust 字符串转换为 UTF-16?

标签 string rust utf-16

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/

相关文章:

rust - rustdoc 是否生成可运行的二进制文件?

c++ - 千分之一符号 (‰) 上的 wctomb 扼流圈

winapi - IMul​​tiLanguage2::ConvertStringFromUnicode - 如何避免复合前缀?

c++ - UTF 8 编码算法与 UTF 16 算法

c# - C# .NET 中的 UTF-16 安全子字符串

string - BITS 数据类型的十六进制字符串表示是什么?

rust - 是否有可能等待一个 &dyn future ?

rust - 我可以使用 Bincode 反序列化具有可变长度前缀的向量吗?

python - 替换字符串中多个字符的最有效方法

c++ - 如何切断字符串的一部分,集合中的每个字符串都有