我正在使用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/