![](/img/trans.png)
[英]How do you merge two arrays of u8 and u16 elements into an array of u8 elements?
[英]Temporarily transmute [u8] to [u16]
我有一个[u8; 16384]
[u8; 16384]
和u16
。 我将如何“临时转换”数组,以便我可以一次设置两个u8
,第一个设置为最低有效字节,第二个设置为最高有效字节?
显而易见、安全和便携的方法是只使用数学。
fn set_u16_le(a: &mut [u8], v: u16) {
a[0] = v as u8;
a[1] = (v >> 8) as u8;
}
如果您想要一个更高级别的接口,则可以使用byteorder
crate 来执行此操作。
您绝对不应该使用transmute
将[u8]
转换为[u16]
,因为这不能保证有关字节顺序的任何内容。
slice::align_to
和slice::align_to_mut
从 Rust 1.30 slice::align_to_mut
是稳定的。 这些函数处理sellibitze提出的对齐问题。
大端和小端的问题仍然是你需要担心的。 您可以使用u16::to_le
类的方法来帮助解决此问题。 但是,我无法使用大端计算机进行测试。
fn example(blob: &mut [u8; 16], value: u16) {
// I copied this example from Stack Overflow without providing
// rationale why my specific case is safe.
let (head, body, tail) = unsafe { blob.align_to_mut::<u16>() };
// This example simply does not handle the case where the input data
// is misaligned such that there are bytes that cannot be correctly
// reinterpreted as u16.
assert!(head.is_empty());
assert!(tail.is_empty());
body[0] = value
}
fn main() {
let mut data = [0; 16];
example(&mut data, 500);
println!("{:?}", data);
}
正如 DK 所建议的那样,您可能不应该真正使用unsafe
代码来重新解释内存……但如果您愿意,可以这样做。
如果你真的想走那条路,你应该注意几个问题:
&mut [u8]
并将其转换为&mut [u16]
,则它可能指的是某些未正确对齐的内存区域,无法作为u16
访问。 根据您运行此代码的计算机,这种未对齐的内存访问可能是非法的。 在这种情况下,程序可能会以某种方式中止。 例如,CPU 可以生成操作系统响应的某种信号以终止进程。 如果您可以切换它(创建一个u16
数组并在字节级别临时处理它),您将解决潜在的内存对齐问题:
/// warning: The resulting byte view is system-specific
unsafe fn raw_byte_access(s16: &mut [u16]) -> &mut [u8] {
use std::slice;
slice::from_raw_parts_mut(s16.as_mut_ptr() as *mut u8, s16.len() * 2)
}
在大端机器上,这个函数不会做你想做的事; 你想要一个小端字节序。 您只能将其用作小端机器的优化,并且需要坚持使用像 DK 那样的大端或混合端机器的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.