ctypes.Structure: string of bytes to Structure
ctypes.Structure: string of bytes to Structure
我想弄清楚如何将 test_data 打包到 TestInfo
from ctypes import Structure, c_char, c_uint8
class TestInfo(Structure):
_fields_ = [
('version', c_uint8),
('lsbyte', c_uint8),
('msbyte', c_uint8),
('free_space', c_uint8 * 2),
('recent_addtime', c_uint8 * 4),
('recent_erasetime', c_uint8 * 4),
('operation_support', c_uint8)
]
test_data = '51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a'
应该这样包装
TestInfo.version = 0x51
TestInfo.lsbyte = 0xaf
...
...
TestInfo.recent_erasetime = 0xf400c760
TestInfo.operation_support = 0x0a
您可以使用以下内容:
import ctypes as ct
class TestInfo(ct.BigEndianStructure):
_pack_ = 1
_fields_ = [('version', ct.c_uint8),
('lsbyte', ct.c_uint8),
('msbyte', ct.c_uint8),
('free_space', ct.c_uint16),
('recent_addtime', ct.c_uint32),
('recent_erasetime', ct.c_uint32),
('operation_support', ct.c_uint8)]
def __repr__(self):
return (f'TestInfo(version={self.version:#02x}, lsbyte={self.lsbyte:#02x}, ' \
f'msbyte={self.msbyte:#02x}, free_space={self.free_space:#04x}, ' \
f'recent_addtime={self.recent_addtime:#08x}, ' \
f'recent_erasetime={self.recent_erasetime:#08x}, ' \
f'operation_support={self.operation_support:#02x})')
test_data = bytes.fromhex('51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a')
test_info = TestInfo.from_buffer_copy(test_data)
print(test_info)
输出:
TestInfo(version=0x51, lsbyte=0xaf, msbyte=0x1, free_space=0x65, recent_addtime=0xf152ff60, recent_erasetime=0xf400c760, operation_support=0xa)
如果不将此结构传递给 C 代码,另一个选项是使用 struct
和 namedtuple
模块。
import struct
from collections import namedtuple
TestInfo = namedtuple('TestInfo','version lsbyte msbyte free_space recent_addtime recent_erasetime operation_support')
test_data = bytes.fromhex('51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a')
test_info = TestInfo(*struct.unpack('>BBBHLLB',test_data))
print(test_info)
print(hex(test_info.recent_erasetime))
输出(十进制值等价,打印一个验证):
TestInfo(version=81, lsbyte=175, msbyte=1, free_space=101, recent_addtime=4048748384, recent_erasetime=4093691744, operation_support=10)
0xf400c760
我想弄清楚如何将 test_data 打包到 TestInfo
from ctypes import Structure, c_char, c_uint8
class TestInfo(Structure):
_fields_ = [
('version', c_uint8),
('lsbyte', c_uint8),
('msbyte', c_uint8),
('free_space', c_uint8 * 2),
('recent_addtime', c_uint8 * 4),
('recent_erasetime', c_uint8 * 4),
('operation_support', c_uint8)
]
test_data = '51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a'
应该这样包装
TestInfo.version = 0x51
TestInfo.lsbyte = 0xaf
...
...
TestInfo.recent_erasetime = 0xf400c760
TestInfo.operation_support = 0x0a
您可以使用以下内容:
import ctypes as ct
class TestInfo(ct.BigEndianStructure):
_pack_ = 1
_fields_ = [('version', ct.c_uint8),
('lsbyte', ct.c_uint8),
('msbyte', ct.c_uint8),
('free_space', ct.c_uint16),
('recent_addtime', ct.c_uint32),
('recent_erasetime', ct.c_uint32),
('operation_support', ct.c_uint8)]
def __repr__(self):
return (f'TestInfo(version={self.version:#02x}, lsbyte={self.lsbyte:#02x}, ' \
f'msbyte={self.msbyte:#02x}, free_space={self.free_space:#04x}, ' \
f'recent_addtime={self.recent_addtime:#08x}, ' \
f'recent_erasetime={self.recent_erasetime:#08x}, ' \
f'operation_support={self.operation_support:#02x})')
test_data = bytes.fromhex('51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a')
test_info = TestInfo.from_buffer_copy(test_data)
print(test_info)
输出:
TestInfo(version=0x51, lsbyte=0xaf, msbyte=0x1, free_space=0x65, recent_addtime=0xf152ff60, recent_erasetime=0xf400c760, operation_support=0xa)
如果不将此结构传递给 C 代码,另一个选项是使用 struct
和 namedtuple
模块。
import struct
from collections import namedtuple
TestInfo = namedtuple('TestInfo','version lsbyte msbyte free_space recent_addtime recent_erasetime operation_support')
test_data = bytes.fromhex('51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a')
test_info = TestInfo(*struct.unpack('>BBBHLLB',test_data))
print(test_info)
print(hex(test_info.recent_erasetime))
输出(十进制值等价,打印一个验证):
TestInfo(version=81, lsbyte=175, msbyte=1, free_space=101, recent_addtime=4048748384, recent_erasetime=4093691744, operation_support=10)
0xf400c760