Python: как упаковать различные типы данных в строковый буфер, используя struct.pack_into - PullRequest
10 голосов
/ 11 мая 2011

Я пытаюсь упаковать некоторые неподписанные данные int в строковый буфер, созданный с использованием ctypes.create_string_buffer.

Ниже приведен следующий сегмент кода и работает пример, показывающий ошибку на кодовой панели :

import struct
import ctypes
import binascii

buf = ctypes.create_string_buffer(16)
struct.pack_into("=I=I=I", buf, 0, 1, 2, 3)
print binascii.hexlify(buf)

Это приводит к следующей ошибке:

...
struct.error: bad char in struct format

Документация не ссылается на то, можете ли вы упаковать данные разных типов, если базовый буфер имеет определенный тип C. В этом случае попытка упаковать данные без знака int в строковый буфер с базовым типом c_char. Кто-нибудь знает решение для этого или есть особый способ создания буфера, который может упаковать данные любого типа?

Ответы [ 3 ]

12 голосов
/ 11 мая 2011

Вы не должны ставить перед каждым спецификатором вывода код '='.Просто скажите это один раз:

struct.pack_into("=III", buf, 0, 1, 2, 3)

Это дает:

01000000020000000300000000000000
4 голосов
/ 18 декабря 2012

Извините, что воскресил старую тему, но я понял, что "защелкиваюсь" - возможно, поражен похожей привычкой фона.

"первый символ строки формата может быть использован для указания порядка байтов,Размер и выравнивание упакованных данных "Я согласен.Однако:

  • Документы Python намеренно (?) Опускают даже один пример использования форматеров порядка () Все примеры предполагают собственный порядок байтов, размер и выравнивание с машиной с прямым порядком байтов.)
  • Можно предположить (как я и , вероятно, snap сделал), что "III" состоит из трех строк формата, и мы можем отформатировать каждую из них по желанию.Отсюда =I=I=I.Я выстрелил себе в ногу после привыкания к массиву Ruby, в котором можно свободно менять порядок следования по выражению (в данном случае эквивалент Ruby равен I_I_I_, так как селектор порядка следует за типом).

Следовательно, я думаю, что было бы неплохо добавить несколько строк в документы struct.pack / unpack, приводя примеры использования порядка и заполнения (ме, заполнение ударило меня еще сильнее ... Я мог жить с собственным порядком, но заполнение разрушеномой протокол).

1 голос
/ 11 мая 2011

Стандартная рабочая процедура: Прочитать сообщение об ошибке.

«плохой символ в формате структуры» означает, что он говорит.

Стандартная рабочая процедура: Проверьте документы . Здесь он говорит: « first [мой акцент] символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных» и переходит к списку = как возможность. В следующем разделе (Формат символов) перечислено много букв , включая I.

Вывод: ваша строка формата должна быть "=III".

Примечание. Проблема вообще не имеет ничего общего с буфером назначения, не говоря уже о его базовом типе C:

>>> import struct
>>> struct.pack("=I=I=I", 1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: bad char in struct format
>>> struct.pack("=III", 1, 2, 3)
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...