为什么原始部分不符合任何字节顺序?
Why does the raw parts not correspond to either endianness?
我正在尝试尽可能多地优化对 u8
数组中的 u32
切片执行的操作。因此,我正在测试不同的选项(循环、迭代器、使用 ByteOrder crate 等)
作为这些测试的一部分,我还想检查是否可以使用 from_raw_parts
标准函数改进它。
这是我的代码:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = &random_bytes as *const _ as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
我本来希望两个 Little 或 Big endian 中至少有一个等于第一个打印,但事实并非如此,例如示例输出
[d951db30]
143600ff
ff003614
[ff, 0, 36, 14]
我做错了什么?
问题在这里:
let view = &random_bytes as *const _ as *const u32;
切片是一个 2 机器字结构,包含指向数据的指针和作为成员的元素计数。
通过执行 &random_bytes
,您正在引用此切片结构(它本身包含一个指针和长度),而不是获取底层指针。
切片有一个 as_ptr 方法,该方法 returns 指向数据本身的指针。当您使用它时,您的代码可以正常运行:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = random_bytes.as_ptr() as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
操场上的输出:
[684a2f5b]
684a2f5b
5b2f4a68
[5b, 2f, 4a, 68]
我正在尝试尽可能多地优化对 u8
数组中的 u32
切片执行的操作。因此,我正在测试不同的选项(循环、迭代器、使用 ByteOrder crate 等)
作为这些测试的一部分,我还想检查是否可以使用 from_raw_parts
标准函数改进它。
这是我的代码:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = &random_bytes as *const _ as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
我本来希望两个 Little 或 Big endian 中至少有一个等于第一个打印,但事实并非如此,例如示例输出
[d951db30]
143600ff
ff003614
[ff, 0, 36, 14]
我做错了什么?
问题在这里:
let view = &random_bytes as *const _ as *const u32;
切片是一个 2 机器字结构,包含指向数据的指针和作为成员的元素计数。
通过执行 &random_bytes
,您正在引用此切片结构(它本身包含一个指针和长度),而不是获取底层指针。
切片有一个 as_ptr 方法,该方法 returns 指向数据本身的指针。当您使用它时,您的代码可以正常运行:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = random_bytes.as_ptr() as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
操场上的输出:
[684a2f5b]
684a2f5b
5b2f4a68
[5b, 2f, 4a, 68]