Ответ 1
Вы не должны префикс каждого спецификатора вывода кодом '='. Просто скажите это один раз:
struct.pack_into("=III", buf, 0, 1, 2, 3)
Это дает:
01000000020000000300000000000000
Я пытаюсь упаковать некоторые неподписанные данные 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. Кто-нибудь знает о решении для этого или существует конкретный способ создания буфера, который может упаковывать данные любого типа?
Вы не должны префикс каждого спецификатора вывода кодом '='. Просто скажите это один раз:
struct.pack_into("=III", buf, 0, 1, 2, 3)
Это дает:
01000000020000000300000000000000
Извините за воскрешение старой темы, но я получаю смысл "привязки" - попадания, вероятно, аналогичной фоновой привычки.
"первый символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных" Я согласен. Однако:
III
" состоит из трех строк форматирования, и мы можем форматировать каждый из них по желанию. Следовательно, =I=I=I
. Я выстрелил себе в ногу после привыкания к Ruby array.pack, где можно свободно изменять порядок вдоль выражения (эквивалент Ruby I_I_I_
в этом случае, поскольку селектор заказов приходит после типа).Следовательно, возможно, было бы неплохо добавить несколько строк в struct.pack/unpack docs, давая примеры использования порядка и дополнений (meh, padding ударил меня еще сильнее... Я мог жить с собственным заказом, но отступы разрушил мой протокол).
Стандартная рабочая процедура: прочитайте сообщение об ошибке.
"bad char в формате структуры" означает, что он говорит.
Стандартная рабочая процедура: проверьте документы. Здесь в нем говорится: "Первый символ [мой акцент] строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных" и далее перечисляет =
как возможность. В следующем разделе (Форматы символов) перечислены многие буквы, включая 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'
>>>