S.R*_*S.R 4 python ctypes python-3.x
我想使用我定义的 ctype.Structure 作为 Python ( b'') 中的字节访问。
不知道是不是正确的方法?我需要向其他设备发送一个标头(它应该是无架构的)。
所以我将它定义为:
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)
]
Run Code Online (Sandbox Code Playgroud)
现在我需要计算CRC。从归档开始version到compilation_time我有一个处理字节的函数。
所以对我来说,只需将 ctypes.Structure 转换为字节(b'')或直接访问内存并更改最后两个字节就可以了。
我试过使用struct但我没有找到pragma选项。
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)
Run Code Online (Sandbox Code Playgroud)
<意味着打包 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 = bytes(h)[:Header.crc.offset] # convert struct to bytes and truncate CRC
print(b)
h.crc = crc32(b) # Set the correct CRC
b = bytes(h) # convert whole struct to bytes
print(b)
Run Code Online (Sandbox Code Playgroud)
输出:
b'\x01\x02\x03\x00ABCDEF'
b'\x01\x02\x03\x00ABCDEF\xe7s\x85\xa6'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4324 次 |
| 最近记录: |