如何在Python中正确声明ctype结构+并集? [英] How Do I Properly Declare a ctype Structure + Union in Python?

查看:87
本文介绍了如何在Python中正确声明ctype结构+并集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搞一个二进制数据解析器,虽然我可以使用C,但是我想看看是否可以使用Python来完成任务。

I'm messing around with making a binary data parser, and while I could fall back on C, I wanted to see if I could use Python for the task.

我对如何执行此操作有所了解,我当前的实现如下所示:

I have some inkling of how to get this going, and my current implementation looks something like this:

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不够了解,无法理解为什么会这样,但是目前这有点违反我的目的。有想法吗?

So... Looks to me like my bytes aren't bytes so much as words. I don't know enough about Python or ctypes to understand why that is, but it's kind of defeating my purpose at the moment. Any ideas?

推荐答案

您的 sHeader 有一个4位字段,然后2位字段,然后是2位字段(总共8位= 1个字节)...但是下一项是 c_uint16 ,需要在2上对齐-byte边界,因此跳过一个字节并移至字节2,然后再取13位。

Your sHeader has a 4 bit field, then a 2 bit field, then a 2 bit field (total 8 bits = 1 byte) ... but then the next item is a c_uint16 which needs to be aligned on a 2-byte boundary and hence skips over a byte and moves to byte 2 before taking 13 bits.

如果您不希望这样做(显然不希望这样做),只需将所有内容都设为 c_uint32 或类似的内容即可:

If you don't want that (and apparently you don't), just make everything a c_uint32 or similar:

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 ,因此打印 s上没有括号。)

(I picked uint32 because your bit fields add up to 32 bits. I'm using Python 2.7 here, hence no parentheses on the prints.)

这篇关于如何在Python中正确声明ctype结构+并集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆