简体   繁体   English

如何将 C 结构反序列化为 Rust 结构

[英]How to deserialize a C struct into a Rust struct

Let's say that there exists a kernel header like this in C:假设在 C 中存在这样的内核头文件:

typedef struct {
  uint32_t type;
  uint32_t length;
  uint32_t extra;
  uint32_t flags;

  uint32_t reserved0;
  uint32_t reserved1;

  uint32_t magic;
  uint32_t crc32;
} zbi_header_t;

That is, the fist bytes of the kernel image are this struct.也就是说,内核映像的第一个字节就是这个结构体。

In order to parse this header into Rust, I'd have something like this:为了将这个头文件解析成 Rust,我有这样的事情:

#[derive(Debug)]
#[repr(C)]
pub struct ZbiHeader {
    zbi_type: u32,
    length: u32,
    extra: u32,
    flags: u32,
    reserved0: u32,
    reserved1: u32,
    magic: u32,
    crc32: u32,
}

notice that I added a repr(C) .请注意,我添加了一个repr(C)

What is the best Rust way to transform a slice &[u8] of size sizeof(zbi_header_t) into this struct?将大小为sizeof(zbi_header_t)的切片&[u8]转换为该结构的最佳 Rust 方法是什么?

Can I take a byte array and deserialize it into a struct? 我可以获取一个字节数组并将其反序列化为一个结构体吗? talks about alignment issues but would we have it here?谈论对齐问题,但我们会在这里吗?

In this particular case where all values are uint32_t I think the compiler wouldn't do any paddings, but I don't know if this is guaranteed and also I'm thinking about what if there was an u8 in the middle.在这种所有值都是 uint32_t 的特殊情况下,我认为编译器不会做任何填充,但我不知道这是否有保证,而且我正在考虑如果中间有一个 u8 会怎样。 It could be that the compiler always disables the paddings for this file?可能是编译器总是禁用此文件的填充? By the way, the header is from https://fuchsia.googlesource.com/fuchsia/+/6d0df1b8f7cbadf04553501f995156b224dd6347/zircon/system/public/zircon/boot/image.h#102 but I couldn't find any rules saying it should ignore paddings, etc.顺便说一句,标题来自https://fuchsia.googlesource.com/fuchsia/+/6d0df1b8f7cbadf04553501f995156b224dd6347/zircon/system/public/zircon/boot/image.h#102但我找不到任何说它应该的规则忽略填充等。

Padding won't be an issue - since you have #[repr(C)] , the representation of the Rust ZbiHeader will match the representation of the C zbi_header_t , padding and all.填充不会成为问题 - 因为你有#[repr(C)] ,Rust ZbiHeader的表示将匹配 C zbi_header_t ,填充和所有的表示。

As for the alignment issues, it entirely depends on how you get your &[u8] byte slice.至于对齐问题,这完全取决于您如何获得&[u8]字节切片。 If you know for a fact that it's a zbi_header_t casted to a byte pointer, then the pointer should be well aligned.如果您知道这是一个zbi_header_t为字节指针的zbi_header_t的事实,那么该指针应该是对齐的。 If you're just grabbing a random &[u8] slice, ex from a file input buffer, then you'd have to worry.如果您只是从文件输入缓冲区中获取一个随机的&[u8]切片,那么您就不得不担心了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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