我正在使用ctypes位字段来剖析紧密打包的二进制数据。我将记录的数据值作为字符串填充到并集中,然后将键字段提取为整数。

当缓冲区中没有空值时,这非常有用,但是任何嵌入的空值都会导致cytpes截断字符串。

例:

from ctypes import *

class H(BigEndianStructure):
    _fields_ = [ ('f1', c_int, 8),
                 ('f2', c_int, 8),
                 ('f3', c_int, 8),
                 ('f4', c_int, 2)
                 # ...
                 ]

class U(Union):
    _fields_ = [ ('fld', H),
                 ('buf', c_char * 6)
                 ]

# With no nulls, works as expected...
u1 = U()
u1.buf='abcabc'
print '{} {} {} (expect: 97 98 99)'.format(u1.fld.f1, u1.fld.f2, u1.fld.f3)

# Embedded null breaks it...  This prints '97 0 0', NOT '97 0 99'
u2 = U()
u2.buf='a\x00cabc'
print '{} {} {} (expect: 97 0 99)'.format(u2.fld.f1, u2.fld.f2, u2.fld.f3)


浏览ctypes源,我看到了两种设置char数组的方法,即CharArray_set_value()和CharArray_set_raw()。看来CharArray_set_raw()可以正确处理null,而CharArray_set_value()不能。

但是我不知道如何调用原始版本...它看起来像一个属性,所以我希望这样:

ui.buf.raw = 'abcabc'


但这会产生:

AttributeError: 'str' object has no attribute raw


任何指导表示赞赏。 (包括完全不同的方法!)

(注意:我需要每秒处理数千条记录,因此效率至关重要。使用数组推导在结构中填充字节数组是可行的,但速度要慢100倍。)

最佳答案

您还可以在struct / union之外创建raw-string数组:

mystring = (c_char * 6).from_buffer(u2)
print mystring.raw


这样,您就没有任何转换开销。
我不知道为什么(c_char * 6)单独使用与在结构/联合中使用时表现不同?

关于python - Python ctypes-在字符串嵌入null时设置c_char数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26278344/

10-14 17:41
查看更多