开发者

Python equivalent of C struct (porting app form C to python)

I'm porting a simple bluetooth app, which sends "magic" packet on L2Cap protocol to bluetooth device..

I have a problem with converting struct object in C to python equivalent..

In 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     开发者_JAVA技巧 value[16];
} __attribute__((packed)) CFGBTFRAME;

static CFGBTFRAME c;

and then in app it's used like that:

        /* 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));

Can you point me out how to construct same packet/stuct-like structure using python?

I know I will probably need to use ctypes and create "empty" class, but how to get all this together?


You can go about it with the struct module to pack values into a byte string, for example:

>>> 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'

Alternatively, you can use ctypes.Structure to define a class that will be representing your structure. It has the advantage of being easier to use with Python code, but you have to take into account alignment and padding issues and resolve them yourself (perhaps with struct).


If your goal is to group a set of key/value in an object, you may use dict or namedtuple.

a dict would be:

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

access: CFGBTFRAME['type']

with namedtuple:

from collections import namedtuple
CFGBTFRAME = namedtuple('CFGBTFRAME', ['type', 'status', ...])
c = CFGBTFRAME()
c.type = myType

see http://docs.python.org/library/collections.html#collections.namedtuple for more information about namedtuple.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜