简体   繁体   中英

Rust, how to slice into a byte array as if it were a float array?

I have some byte data stred in a &[u8] I know for a fact the data contained in the slice is float data. I want to do the equivalent of auto float_ptr = (float*)char_ptr;

I tried:

let data_silce = &body[buffer_offset..(buffer_offset + buffer_length)] as &[f32];

But you are not allowed to execute this kind of casting in rust.

You will need to use unsafe Rust to interpret one type of data as if it is another.

You can do:

let bytes = &body[buffer_offset..(buffer_offset + buffer_length)];

let len = bytes.len();
let ptr = bytes.as_ptr() as *const f32;
let floats: &[f32] = unsafe { std::slice::from_raw_parts(ptr, len / 4)};

Note that this is Undefined Behaviour if any of these are true:

  • the size of the original slice is not a multiple of 4 bytes
  • the alignment of the slice is not a multiple of 4 bytes

All sequences of 4 bytes are valid f32 s but, for types without that property, to avoid UB you also need to make sure that all values are valid.

Use the bytemuck library; specifically bytemuck::cast_slice() . Underneath, it is just the unsafe conversion that has already been described in other answers, but it uses compile-time (type) and run-time (length and alignment) checks to ensure that you don't have to worry about correctly checking the safety conditions.

let data_slice: &[f32] = bytemuck::cast_slice(
    &body[buffer_offset..(buffer_offset + buffer_length)
];

Note that this will panic if the beginning and end of the slice are not aligned to 4 bytes. There is no way to avoid this requirement in Rust — if the data is not aligned, you must copy it to a new location that is aligned. (Since your goal is to produce f32 s, the simplest way to do that while ensuring the alignment would be to iterate with f32::from_ne_bytes() , performing the f32 conversion and the copy.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM