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

实现C结构体字节写入文件的最简Python等效方案

实现与C嵌套结构体字节写入等效的最简Python代码

核心思路

要实现和C嵌套结构体一致的连续字节写入,关键是按C的内存布局(字节序、对齐规则、字段长度)把数据逐层转成字节流,下面提供两种可行方案,解决struct模块无法递归解包嵌套对象的问题。


方案一:用struct递归处理嵌套结构

针对*解包符无法递归处理嵌套可迭代对象的问题,写一个递归打包函数,自动处理嵌套的元组/namedtuple:

import struct
from collections import namedtuple

# 定义结构体格式(@表示系统默认字节序和对齐,和C一致)
# 对应C结构体:
# typedef struct { int id; char name[8]; } SubData;
# typedef struct { float value; SubData sub; } MainData;
SUB_FMT = "i 8s"
MAIN_FMT = "f " + SUB_FMT

def recursive_pack(data):
    """递归打包嵌套数据为字节流"""
    if isinstance(data, (tuple, namedtuple)):
        if len(data) == 2:  # 匹配SubData字段数
            return struct.pack(SUB_FMT, *data)
        elif len(data) == 3:  # 匹配MainData字段数
            main_part = struct.pack("f", data[0])
            sub_part = recursive_pack(data[1])
            return main_part + sub_part
    return struct.pack(SUB_FMT if len(data)==2 else MAIN_FMT, *data)

# 构造示例数据(namedtuple和普通元组都支持)
SubData = namedtuple("SubData", ["id", "name"])
MainData = namedtuple("MainData", ["value", "sub"])

sub_data = SubData(1, b"hello\0\0\0")  # char[8]需补满8字节,不足用\0填充
main_data = MainData(12.5, sub_data)

# 写入文件
with open("output.bin", "wb") as f:
    f.write(recursive_pack(main_data))

关键说明

  • 递归函数自动识别嵌套结构,先处理子结构体再拼接主结构字节
  • 如果C结构体用了紧凑打包(如__attribute__((packed))),把格式符里的@换成=即可(例:SUB_FMT = "=i 8s")
  • namedtuple可直接传入,因为它是元组的子类

方案二:手动拼接字节(不依赖struct/namedtuple)

如果不想用这两个模块,直接手动转换每个字段为字节再拼接,完全控制字节流:

def int_to_bytes(num, byte_len=4, little_endian=False):
    """把整数转成指定长度的字节,默认4字节对应C的int"""
    return num.to_bytes(byte_len, 
                       byteorder="little" if little_endian else "big",
                       signed=True)

def float_to_bytes(val):
    """把浮点数转成4字节对应C的float"""
    import struct
    return struct.pack("f", val)

# 构造数据
sub_id = 1
sub_name = b"hello" + b"\0"*3  # 补满8字节匹配char[8]
main_value = 12.5

# 按C结构体顺序拼接所有字节
byte_stream = float_to_bytes(main_value) + int_to_bytes(sub_id) + sub_name

# 写入文件
with open("output.bin", "wb") as f:
    f.write(byte_stream)

关键说明

  • 所有字符数组必须手动补满长度,确保和C定义一致
  • 字节序要和C代码匹配,小端序系统需在int_to_bytes里指定little_endian=True
  • 这种方式适合结构简单的场景,无需处理复杂嵌套

验证方法

可以用binascii模块查看输出文件的十六进制,和C代码生成的文件对比:

import binascii
with open("output.bin", "rb") as f:
    print(binascii.hexlify(f.read()).decode())

内容的提问来源于stack exchange,提问作者First User

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:55:12