如何从文件中读取结构化二进制数据?

How to read structured binary data from a file?

以下 C++ 代码将 header 写入文件:

#include <iostream>

struct Header
{
    uint16_t name;
    uint8_t type;
    uint8_t padding;
    uint32_t width, height;
    uint32_t depth1, depth2;
    float dMin, dMax;
};

int main()
{

  Header header;
  header.name = *reinterpret_cast<const uint16_t*>("XO");
  header.type = true;
  header.width  = (uint32_t)512;
  header.height = (uint32_t)600;
  header.depth1  = (uint32_t)16;
  header.depth2 = (uint32_t)25;
  header.dMin = 5.0;
  header.dMax = 8.6;

  FILE* f = fopen("header.bin", "wb");
    fwrite(&header, sizeof(Header), 1, f);
}

我希望使用 Python 阅读这些 header.bin 文件。在 C++ 中,我会做类似的事情:

fread(&header, sizeof(Header), 1, f)

但我不确定如何读取字节并将它们转换为 Header 结构在 Python 中具有的相应字段?

我会用 Python 的 ctypes 做这个,这样你就可以分享 Header header

ctypes.Structure 创建一个 class 来映射类型

import ctypes

class StructHeader(ctypes.Structure):
    _fields_ = [
        ("name", ctypes.c_uint16),
        ("type", ctypes.c_uint8),
        ...
    ]

并创建一个函数,它可以用像

这样的签名来做你想做的事
int header(struct Header &buffer)
{
    // open the file and write to buffer
    // opportunity for other features
}

然后你可以编译一个shared object来读取它returns那个类型

gcc -shared -Wl,-soname,your_soname \
    -o library_name file_list library_list

并用 ctypes.CDLL 呼出阅读 headers

header = ctypes.CDLL("mylib.so.1").header  # function named header
header.argtypes = [ctypes.POINTER(StructHeader)]
header.restype  = ctypes.c_int

# allocate struct for write
buffer = StructHeader()

# call out to function to write buffer
header(buffer)

使用 struct module 定义类 C 结构的二进制布局,de-/serialise 它:

import struct

# Format String describing the data layout
layout = "H B x 2L 2L 2f"

# Object representing the layout, including size
header = struct.Struct(layout)

with open("header.bin", "rb") as in_stream:
    print(header.unpack(in_stream.read(header.size))

layout 是一个 format string 描述字段的顺序,例如H 表示 uint16_tB 表示 uint8_tx 表示填充字节,依此类推。