如何将ctypes转换为字节

时间:2017-03-07 15:42:37

标签: python python-3.x ctypes

我想访问我已定义的ctype.Structure,作为Python中的字节(https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js; https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.min.js; )。

我不知道这是正确的方法吗?我需要向其他设备发送一个标题(它应该是免费的架构)。

所以我把它定义为例如:

b''

现在我需要计算CRC。从 class Header(ctypes.Structure): _pack_ = 2 _fields_ = [ ('version', c_uint8), ('additional_options', c_uint8), ('soft_version', c_uint16), ('compilation_time', c_uint8 * 6), ('crc', c_uint16) ] 提交到version我有一个可以使用字节的函数。

所以对我来说,只需将ctypes.Structure转换为字节(b'')或直接访问内存并更改最后两个字节即可。

我尝试过使用struct,但我没有找到 pragma 选项。

1 个答案:

答案 0 :(得分:3)

struct就是你想要的:

>>> import struct
>>> fmt = struct.Struct('<BBH6s')
>>> data = fmt.pack(1,2,3,b'170207')
>>> data
b'\x01\x02\x03\x00170207'
>>> crc = <do your calculation>
>>> data += struct.pack('<H',crc)

<表示打包little-endian并且不会像C那样添加填充字节,因此不需要_pack_。如果您需要big-endian,请改用>

我使用6s并传递了一段正确长度的字节字符串。如果要传递原始字节而不是使用6B并列出6个字节而不是一个字符串。

这是一个ctypes解决方案。我使用了crc32,因为库中有一个用于演示目的。

from ctypes import *
from binascii import crc32

class Header(Structure):
    _pack_ = 2
    _fields_ = [
        ('version', c_uint8),
        ('additional_options', c_uint8),
        ('soft_version', c_uint16),
        ('compilation_time', c_uint8 * 6),
        ('crc', c_uint32)
    ]

h = Header(1,2,3)
h.compilation_time = (c_uint8 * 6)(*b'ABCDEF')
b = string_at(addressof(h),sizeof(h)-Header.crc.size)
print(b)
h.crc = crc32(b)
b = string_at(addressof(h),sizeof(h))
print(b)

输出:

b'\x01\x02\x03\x00ABCDEF'
b'\x01\x02\x03\x00ABCDEF\xe7s\x85\xa6'