Python等价于C结构体(将应用程序形式C移植到Python)



我正在移植一个简单的蓝牙应用程序,它在L2Cap协议上发送"魔法"数据包到蓝牙设备。

我在将C中的struct对象转换为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;

然后在app中是这样使用的:

        /* 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并创建"空"类,但是如何将所有这些结合在一起?

您可以使用struct模块将值打包成字节字符串,例如:

>>> import struct
>>> type, status, varid, value = 1, 0, 16, b'Hello'
>>> buffer = struct.pack('>BBH16s', type, status, varid, value)
>>> buffer
b'x01x00x00x10Hellox00x00x00x00x00x00x00x00x00x00x00'

或者,您可以使用ctypes.Structure来定义一个表示您的结构的类。它的优点是更容易与Python代码一起使用,但您必须考虑对齐和填充问题并自己解决它们(可能使用struct)。

如果您的目标是对对象中的一组键/值进行分组,您可以使用dictnamedtuple

字典应该是:

CFGBTFRAME = {
    'type' : myType,
    'status' : ...
}

访问:CFGBTFRAME['类型']

与namedtuple:

from collections import namedtuple
CFGBTFRAME = namedtuple('CFGBTFRAME', ['type', 'status', ...])
c = CFGBTFRAME()
c.type = myType
关于namedtuple的更多信息,请参见http://docs.python.org/library/collections.html#collections.namedtuple

最新更新