我有一个从磁盘读取
Vec<u8>
的函数,我想将其解释为 ext2 超级块(这是一个打包结构)。
所以我用了:
unsafe {&*(raw_super.as_ptr() as *const Super block)}
问题是当函数返回时
Vec
被丢弃,所以超级块只有0s
我想要一种将 Vec 转换为超级块并拥有超级块中的数据的方法,如果可能的话,需要小的成本抽象
正如其他人之前在评论中指出的那样,您必须首先断言几个先决条件:
u8
和 #[repr(packed)]
结构始终满足这一点vec.len()
)正确因此您可以将
Vec<u8>
转换为 Box<SuperBlock>
,如下所示:
// `C` so the order of the fields in memory is known
// `packed` so the alignment is 1 and there is no padding
#[repr(C, packed)]
struct SuperBlock {
foo: u16,
bar: u32,
}
// ext2 superblocks are always little endian, so this works only for those platforms
#[cfg(target_endian = "little")]
impl SuperBlock {
/// ## Errors
/// Returns the vector when it's lenght isn't exactly the size of a `SuperBlock`
pub fn from_vec(v: Vec<u8>) -> Result<Box<Self>, Vec<u8>> {
if v.len() != std::mem::size_of::<SuperBlock>() {
return Err(v);
}
// SAFETY:
// `#[repr(packed)] structs have an alignment of 1, the same as u8
// v.len() and size_of::<SuperBlock>() are the same as asserted above
Ok(unsafe { Box::from_raw(Box::into_raw(v.into_boxed_slice()).cast::<SuperBlock>()) })
}
}