Temporarily transmute [u8] to [u16]

I have [u8; 16384]and a u16. How would I “temporarily transmute” an array to immediately set two u8, the first with the least significant byte, and the second on the most significant byte?

+4
source share
3 answers

As DK suggests , you probably shouldn't use unsafecode to rethink memory ... but you can if you want.

If you really want to go this route, you should know a couple of errors:

  • You may have an alignment problem. If you just take it from somewhere &mut [u8]and convert it to &mut [u16], it may refer to some area of ​​memory that is not properly aligned to access it as u16. Depending on which computer you are running this code on, such unaligned memory access may not be acceptable. In this case, the program is likely to be interrupted somehow. For example, a processor may generate some kind of signal that the operating system responds to complete the process.
  • It will be unbearable. Even without the alignment problem, you will get different results on different machines (ordinal machines little- and big-).

( u16 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)
}

big- , ; little-. little-, , DK, big- .

+3

, .

fn set_u16_le(a: &mut [u8], v: u16) {
    a[0] = v as u8;
    a[1] = (v >> 8) as u8;
}

, byteorder , .

transmute, [u8] [u16], .

+11

slice::align_toand stable with Rust 1.30. These functions handle the alignment problems that Sellibitze causes . slice::align_to_mut

Byte ordering problems big- and little- may still bother you. You can use methods such as to help with this. However, I do not have access to a computer with a big- byte order for testing. 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);
}
0
source

Source: https://habr.com/ru/post/1617812/


All Articles