Ctypes创建BigEndianStructure返回4字节而非3字节的原因是什么
问题原因分析
1. 位域基础类型决定分配单元大小
ctypes中位域的存储会优先以你指定的字段基础类型的大小作为最小分配单元。你代码中两个位域的基础类型都是c_uint,该类型在绝大多数平台上为4字节无符号整数,即便你只用到了其中的3位(1位+2位),整个位域分配单元也会占满4字节的空间,这就是结构大小为4字节的核心原因。
你设置的_pack_ = 1仅能控制不同结构成员之间的填充对齐规则,无法修改位域对应的基础类型本身的大小,所以这里不会生效。
2. 输出结果对应逻辑说明
你当前运行得到的b'\x00\x00\x00'`是符合逻辑的:
- 结构是大端序,
nal_unit_f=0(1位) +nal_unit_ref=3(2位)拼接后前3位为0b011 - 剩余5位补0后第一个字节为
0b01100000即十六进制0x60,对应ASCII字符`,后面3个字节为4字节单元的填充位,均为0,最终输出和你得到的结果一致。
3. 期望输出适配方案
你期望得到3字节的b'\x00\x01\x01',和当前位域的定义逻辑不匹配:当前两个字段加起来仅占3位,连1字节都不到,不可能输出3字节的结果。如果你的需求是3个独立的单字节字段,不使用位域即可:
from ctypes import * class NAL_UNIT_SHORT(BigEndianStructure): _pack_ = 1 _fields_ = [("nal_unit_f", c_uint8), ("nal_unit_ref1", c_uint8), ("nal_unit_ref2", c_uint8)] print(bytes(NAL_UNIT_SHORT(0, 1, 1))) print(sizeof(NAL_UNIT_SHORT))
运行后即可得到你期望的3字节输出,结构大小也为3字节。
如果你需要的是3位占1字节的位域结构
将基础类型替换为1字节的c_uint8即可,修改后结构大小为1字节:
from ctypes import * class NAL_UNIT_SHORT(BigEndianStructure): _pack_ = 1 _fields_ = [("nal_unit_f", c_uint8, 1), ("nal_unit_ref", c_uint8, 2)] print(bytes(NAL_UNIT_SHORT(0, 3))) print(sizeof(NAL_UNIT_SHORT))
运行输出:
b'`' 1
内容的提问来源于stack exchange,提问作者Christoph Acs
相关产品推荐
相关产品推荐

