You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将文件中存储的C结构体数据读取到Python数据类中?

如何将文件中存储的C结构体数据读取到Python数据类中?

当然有比手动字节偏移更优雅的方案啦!不用再对着字节数一点点算位置,我们可以结合Python标准库和数据类的特性来实现,甚至可以用装饰器把逻辑封装得更整洁。

方法一:用struct模块+数据类工厂方法

Python的struct模块专门用来处理C风格的字节结构,我们可以给数据类添加一个类方法,直接从文件读取并解析数据:

首先导入必要的模块:

from dataclasses import dataclass
import struct

然后定义你的数据类并添加解析方法:

@dataclass
class Boh:
    a: int
    b: int
    c: bool

    @classmethod
    def from_file(cls, file_path):
        # 格式字符串说明:
        # <:小端字节序(如果写入文件时用的是大端,换成>;本机字节序用=)
        # I:对应C的uint32_t(4字节无符号整数)
        # b:对应C的int8_t(1字节有符号整数)
        # ?:对应C的bool/boolean(1字节布尔值)
        format_str = '<I b ?'
        
        with open(file_path, 'rb') as f:
            # 读取刚好对应结构体大小的字节
            raw_data = f.read(struct.calcsize(format_str))
            # 解析字节为对应的值
            a_val, b_val, c_val = struct.unpack(format_str, raw_data)
            return cls(a=a_val, b=b_val, c=c_val)

使用的时候就很简单了:

# 从文件读取并生成Boh实例
my_boh = Boh.from_file("boh_data.bin")

方法二:用装饰器封装解析逻辑(更复用)

如果你有多个结构体需要处理,写重复的工厂方法太麻烦,可以自定义一个装饰器,把struct解析逻辑封装起来,直接给数据类打个装饰器就能用:

先写装饰器:

import struct
from dataclasses import dataclass

def struct_dataclass(format_str):
    def decorator(cls):
        # 添加入参为字节数据的解析方法
        @classmethod
        def from_bytes(cls, byte_data):
            unpacked_vals = struct.unpack(format_str, byte_data)
            return cls(*unpacked_vals)
        
        # 添加入参为文件路径的解析方法
        @classmethod
        def from_file(cls, file_path):
            with open(file_path, 'rb') as f:
                byte_size = struct.calcsize(format_str)
                raw_data = f.read(byte_size)
                return cls.from_bytes(raw_data)
        
        # 把方法绑定到数据类上
        cls.from_bytes = from_bytes
        cls.from_file = from_file
        return cls
    return decorator

然后用装饰器修饰你的数据类:

@struct_dataclass('<I b ?')
@dataclass
class Boh:
    a: int
    b: int
    c: bool

这样不管多少个结构体,只要给装饰器传入对应的格式字符串,就能直接用from_file或from_bytes方法解析了!

重要注意事项:内存对齐问题

C编译器会自动给结构体成员做内存对齐(比如为了性能,把成员对齐到4字节或8字节边界),这会导致结构体的实际大小比成员字节数之和大。比如你的struct boh,如果编译器默认对齐到4字节,那么int8_t b后面会填充3个空字节,总大小会是8字节而不是6字节。

这时候你需要调整struct的格式字符串,加上填充字节的占位符:

  • 比如上面的情况,格式字符串要改成<I b 3x ?,其中3x表示跳过3个填充字节。

你可以在C代码里用sizeof(struct boh)算出实际大小,再对比Python里struct.calcsize(format_str)的结果,如果不一致,就说明有填充,需要补充对应的x占位符。

备注:内容来源于stack exchange,提问作者Brendon Mendicino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:03:07