Python中C结构的等效实现(将应用程序从C移植到Python)
我正在移植一个简单的蓝牙应用程序,这个程序通过L2Cap协议向蓝牙设备发送“魔法”数据包。
我遇到了一个问题,就是如何把C语言中的结构体对象转换成Python中的对应结构。
在C语言中:
/* command types */
#define CFGBT_TYPE_SETREQ 0x00
#define CFGBT_TYPE_SETRES 0x01
#define CFGBT_TYPE_GETREQ 0x02
#define CFGBT_TYPE_GETRES 0x03
/* varid types */
#define CFG_VARIDT_UINT16 0x0000
#define CFG_VARIDT_UINT32 0x1000
#define CFG_VARIDT_STRING16 0x2000
typedef struct {
uint8_t type, status;
uint16_t varid;
uint8_t value[16];
} __attribute__((packed)) CFGBTFRAME;
static CFGBTFRAME c;
然后在应用程序中是这样使用的:
/* set up */
c.type = CFGBT_TYPE_GETREQ;
c.varid = strtol(argv[3], NULL, 0);
c.status = 0;
memset(c.value, 0, 16);
/* send frame */
write(s, &c, sizeof(c));
你能告诉我如何用Python构建一个相同的数据包或类似结构吗?
我知道我可能需要使用ctypes,并创建一个“空”的类,但我该如何把这些结合起来呢?
2 个回答
0
如果你的目标是把一组键值对放在一个对象里,你可以使用 dict
(字典)或者 namedtuple
(命名元组)。
用字典的方式可以这样写:
CFGBTFRAME = {
'type' : myType,
'status' : ...
}
访问字典里的值可以用:CFGBTFRAME['type']
如果用命名元组的话,可以这样:
from collections import namedtuple
CFGBTFRAME = namedtuple('CFGBTFRAME', ['type', 'status', ...])
c = CFGBTFRAME()
c.type = myType
想了解更多关于命名元组的信息,可以查看这个链接:http://docs.python.org/library/collections.html#collections.namedtuple。
3
你可以使用 struct
模块把一些值打包成字节串,举个例子:
>>> import struct
>>> type, status, varid, value = 1, 0, 16, b'Hello'
>>> buffer = struct.pack('>BBH16s', type, status, varid, value)
>>> buffer
b'\x01\x00\x00\x10Hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
另外,你也可以用 ctypes.Structure
来定义一个类,这个类用来表示你的结构。这样做的好处是用起来更方便,但你需要注意对齐和填充的问题,这些问题需要你自己解决(可能需要用到 struct
)。