如何正确声明一个CTYPE结构+联盟在Python?(How Do I Properly Decla

2019-09-16 19:30发布

我瞎搞与进行二进制数据解析器,而我可以依傍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的明白这是为什么,但它目前那种打败我的目的。 有任何想法吗?

Answer 1:

您的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秒。)



Answer 2:

您可以控制与对齐_pack_类属性:

class sHeader(Structure):
    _pack_ = 1

结果是

4294967295
255
<Field type=c_ubyte, ofs=3, size=1>
<Field type=c_ushort, ofs=1:15, bits=1>
<Field type=c_ushort, ofs=1:14, bits=1>
<Field type=c_ushort, ofs=1:13, bits=1>
<Field type=c_ushort, ofs=1: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>
4
1
2
4


文章来源: How Do I Properly Declare a ctype Structure + Union in Python?