Rust 将 Vec<u8> 转换为不同的结构,并删除 Vec,同时拥有其他结构的所有权

问题描述 投票:0回答:1

我有一个从磁盘读取

Vec<u8>
的函数,我想将其解释为 ext2 超级块(这是一个打包结构)。

所以我用了:

unsafe {&*(raw_super.as_ptr() as *const Super block)}

问题是当函数返回时

Vec
被丢弃,所以超级块只有0s

我想要一种将 Vec 转换为超级块并拥有超级块中的数据的方法,如果可能的话,需要小的成本抽象

rust unsafe
1个回答
0
投票

正如其他人之前在评论中指出的那样,您必须首先断言几个先决条件:

  • 字节序正确(ext2 使用小字节序)
  • 对齐是正确的,但
    u8
    #[repr(packed)]
    结构始终满足这一点
  • 尺寸(
    vec.len()
    )正确
  • 结构体中字段的顺序是已知的

所以你可以像这样转换你的

Vec<u8>

// `C` for order of the fields
// `packed` for alignmend and 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>()) })
    }
}

游乐场

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.