Python-эквивалент C struct (портирование формы приложения C на python) - PullRequest
3 голосов
/ 19 сентября 2011

Я портирую простое приложение Bluetooth, которое отправляет «волшебный» пакет по протоколу L2Cap на устройство Bluetooth.

У меня проблема с преобразованием объекта struct в 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 ]

3 голосов
/ 19 сентября 2011

Вы можете сделать это с помощью модуля 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, чтобы определить класс, который будет представлять вашу структуру. Его преимущество в том, что его проще использовать с кодом Python, но вы должны учитывать проблемы выравнивания и дополнения и решать их самостоятельно (возможно, с помощью struct).

0 голосов
/ 19 сентября 2011

Если ваша цель состоит в том, чтобы сгруппировать набор ключа / значения в объекте, вы можете использовать dict или namedtuple.

, а голос будет:

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

доступ: CFGBTFRAME ['type']

с namedtuple:

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

см. http://docs.python.org/library/collections.html#collections.namedtuple для получения дополнительной информации о namedtuple.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...