C-like structures in Python
bytes转Structure
def convert_bytes_to_structure(st: object, byte: bytes):
assert ctypes.sizeof(st) ==len(byte),'size error! need:%d,give:%d'%(ctypes.sizeof(st),len(byte))
# ctypes.memmove(ctypes.pointer(st), byte, ctypes.sizeof(st))
ctypes.memmove(ctypes.addressof(st), byte, ctypes.sizeof(st))
使用ctypes Structure来转换c中的结构体
class TYPE_BASE(ctypes.LittleEndianStructure):
_pack_: int = 1
def __init__(self, data: Union[bytes, list, tuple, set]) -> None:
if isinstance(data, bytes):
convert_bytes_to_structure(self, data)
elif isinstance(data, (list, tuple, set)):
convert_bytes_to_structure(self, bytes(data))
elif isinstance(data, io.IOBase):
data.readinto(self)
'''
struct MyClass{
int val1;
int val2;
char buf[10];
};
'''
class MyClass(TYPE_BASE):
# _pack_: int = 1
_fields_: list = [
("val1", ctypes.c_int32),
("val2", ctypes.c_int32),
("buf", ctypes.c_byte * 10),
]
# def __init__(self, data: Union[bytes, list, tuple, set]) -> None:
# super().__init__(data)
def __str__(self) -> str:
info=''
info+='val1:%s\n'%self.val1
info+='val2:%s\n'%self.val2
info+='buf:%s\n'%bytes(self.buf)
return info
def test_ty():
# data=[1,0,0,0,2,0,0,0]+list(b'a'*10)
data=int.to_bytes(1,4,'little')+int.to_bytes(2,4,'little')+b'a'*10
obj=MyClass(data)
print('bytes(obj):',bytes(obj))
print(obj)
data2=[10,0,0,0,20,0,0,0]+list(b'b'*10)
#do not call __init__; use from_buffer_copy
obj2=MyClass.from_buffer_copy(bytes(data2))
print('bytes(obj2):',bytes(obj2))
print(obj2)
输出:
bytes(obj): b'\x01\x00\x00\x00\x02\x00\x00\x00aaaaaaaaaa'
val1:1
val2:2
buf:b'aaaaaaaaaa'
bytes(obj2): b'\n\x00\x00\x00\x14\x00\x00\x00bbbbbbbbbb'
val1:10
val2:20
buf:b'bbbbbbbbbb'