Tux*_*ude 11 python struct ctypes binary-data bit-fields
我正在为二进制格式编写解析器.这种二进制格式涉及不同的表,这些表再次是二进制格式,通常包含不同的字段大小(大约在50到100之间).
这些结构中的大多数将具有位域,并且在用C表示时将看起来像这些:
struct myHeader
{
unsigned char fieldA : 3
unsigned char fieldB : 2;
unsigned char fieldC : 3;
unsigned short fieldD : 14;
unsigned char fieldE : 4
}
Run Code Online (Sandbox Code Playgroud)
我遇到了struct模块,但意识到它的最低分辨率是一个字节而不是一点,否则该模块几乎适合这项工作.
我知道使用ctypes支持位域,但我不知道如何在这里连接包含位域的ctypes结构.
我的另一个选择是自己操作这些位并将其提供给字节并将其与struct模块一起使用 - 但由于我有接近50-100种不同类型的此类结构,因此编写代码变得更容易出错.我也担心效率,因为这个工具可能用于解析大千兆字节的二进制数据.
谢谢.
使用位串(您提到您正在查看)应该很容易实现。首先创建一些要解码的数据:
>>> myheader = "3, 2, 3, 14, 4"
>>> a = bitstring.pack(myheader, 1, 0, 5, 1000, 2)
>>> a.bin
'00100101000011111010000010'
>>> a.tobytes()
'%\x0f\xa0\x80'
Run Code Online (Sandbox Code Playgroud)
然后再次解码它只是
>>> a.readlist(myheader)
[1, 0, 5, 1000, 2]
Run Code Online (Sandbox Code Playgroud)
您主要关心的很可能是速度。该库是经过良好优化的 Python,但速度不如 C 库快。
我没有严格测试过这个,但它似乎适用于无符号类型(编辑:它也适用于有符号字节/短类型).
编辑2:这真的很受欢迎.这取决于库的编译器将这些位打包到结构中的方式,这不是标准化的.例如,因为我不使用属性收拾结构,即用gcc 4.5.3它的工作原理,只要__attribute__ ((__packed__))(所以不是6个字节被打包成4个字节,你可以检查__alignof__和sizeof).我可以通过添加_pack_ = True到ctypes结构定义来使它几乎工作,但它对于fieldE失败了.gcc说明:"GCC 4.4中"填充位字段'fieldE'的偏移已经改变.
import ctypes
class MyHeader(ctypes.Structure):
_fields_ = [
('fieldA', ctypes.c_ubyte, 3),
('fieldB', ctypes.c_ubyte, 2),
('fieldC', ctypes.c_ubyte, 3),
('fieldD', ctypes.c_ushort, 14),
('fieldE', ctypes.c_ubyte, 4),
]
lib = ctypes.cdll.LoadLibrary('C/bitfield.dll')
hdr = MyHeader()
lib.set_header(ctypes.byref(hdr))
for x in hdr._fields_:
print("%s: %d" % (x[0], getattr(hdr, x[0])))
Run Code Online (Sandbox Code Playgroud)
输出:
fieldA: 3
fieldB: 1
fieldC: 5
fieldD: 12345
fieldE: 9
Run Code Online (Sandbox Code Playgroud)
C:
typedef struct _MyHeader {
unsigned char fieldA : 3;
unsigned char fieldB : 2;
unsigned char fieldC : 3;
unsigned short fieldD : 14;
unsigned char fieldE : 4;
} MyHeader, *pMyHeader;
int set_header(pMyHeader hdr) {
hdr->fieldA = 3;
hdr->fieldB = 1;
hdr->fieldC = 5;
hdr->fieldD = 12345;
hdr->fieldE = 9;
return(0);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5229 次 |
| 最近记录: |