9

私はバイナリデータパーサーの作成をいじっています。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については、その理由を理解するのに十分な知識はありませんが、現時点では私の目的を打ち破っているようなものです。何か案は?

4

2 に答える 2

9

あなたsHeaderは4ビットフィールド、次に2ビットフィールド、次に2ビットフィールド(合計8ビット= 1バイト)を持っています...しかし、次の項目はc_uint162バイト境界に整列する必要があるためスキップします1バイトを超え、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>

(ビットフィールドの合計が32ビットになるため、uint32を選択しました。ここではPython 2.7を使用しているため、printsに括弧はありません。)

于 2012-04-27T07:33:13.213 に答える
5

_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
于 2012-04-27T09:39:05.530 に答える