python - 如何在 Python 中正确声明 ctype 结构 + 联合?

标签 python struct byte ctypes unions

我正在忙着制作一个二进制数据解析器,虽然我可以求助于 C,但我想看看我是否可以使用 Python 来完成这项任务。

我对如何实现这一点有一些了解,我当前的实现看起来像这样:

from ctypes import *

class sHeader(Structure):
    _fields_ = [("CC", c_uint8, 4),
            ("AFC", c_uint8, 2),
            ("TSC", c_uint8, 2),
            ("PID", c_uint16, 13),
            ("TP", c_uint16, 1),
            ("PSI", c_uint16, 1),
            ("TEI", c_uint16, 1),
            ("SyncByte", c_uint8)]

class Header(Union):
    _fields_ = [("sData", sTsHeader),
            ("ulData", c_uint32)]

head = Header()
head.ulData = 0xffffffff
print(head.ulData)
print(head.sData.SyncByte)

print(sHeader.SyncByte)
print(sHeader.TEI)
print(sHeader.PSI)
print(sHeader.TP)
print(sHeader.PID)
print(sHeader.TSC)
print(sHeader.AFC)
print(sHeader.CC)


print(sizeof(sHeader))
print(sizeof(c_uint8))
print(sizeof(c_uint16))
print(sizeof(c_uint32))

产生这个输出:

V:\>C:\Python27\python.exe WidiUnpacker.py
0xffffffffL
0x0
<Field type=c_ubyte, ofs=4, size=1>
<Field type=c_ushort, ofs=2:15, bits=1>
<Field type=c_ushort, ofs=2:14, bits=1>
<Field type=c_ushort, ofs=2:13, bits=1>
<Field type=c_ushort, ofs=2:0, bits=13>
<Field type=c_ubyte, ofs=0:6, bits=2>
<Field type=c_ubyte, ofs=0:4, bits=2>
<Field type=c_ubyte, ofs=0:0, bits=4>
6
1
2
4

所以...在我看来我的字节与其说是字节不如说是单词。我对 Python 或 ctypes 的了解还不够,无法理解为什么会这样,但目前这有点违背我的目的。有什么想法吗?

最佳答案

您的 sHeader 有一个 4 位字段,然后是一个 2 位字段,然后是一个 2 位字段(总共 8 位 = 1 个字节)...但是下一项是 c_uint16 需要在 2 字节边界上对齐,因此会跳过一个字节并在占用 13 位之前移动到字节 2。

如果你不想要那个(显然你不想要),只需将所有内容都设为 c_uint32 或类似的:

from ctypes import *

class sHeader(Structure):
    _fields_ = [("CC", c_uint32, 4),
        ("AFC", c_uint32, 2),
        ("TSC", c_uint32, 2),
        ("PID", c_uint32, 13),
        ("TP", c_uint32, 1),
        ("PSI", c_uint32, 1),
        ("TEI", c_uint32, 1),
        ("SyncByte", c_uint32, 8)] # note: added 8 here

print sHeader.PID
print sHeader.SyncByte

结果:

<Field type=c_uint, ofs=0:8, bits=13>
<Field type=c_uint, ofs=0:24, bits=8>

(我选择 uint32 是因为你的位字段加起来是 32 位。我在这里使用的是 Python 2.7,因此 print 上没有括号。)

关于python - 如何在 Python 中正确声明 ctype 结构 + 联合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10346375/

相关文章:

go - 如何选择在运行时更新哪个结构成员?

Python - 线程 - 我可以制作线程队列列表吗?

python - 如何在 Pygame 中每次重置游戏时初始化新对象

c - 为 'struct ** record' 的属性赋值

c - 在内存中存储各个位

c# - .NET 是否提供了一种将字节转换为 KB、MB、GB 等的简单方法?

java - 从不使总和为负的数据类型

python - 如何比较两个列表中的项目 Python 3.3

java - 使用 numpy.fromfile 在 Python 中使用 ObjectOutputStream 读取用 Java 编写的 double 的二进制文件

json - 无法将 json 数据反序列化为结构