Aarrrgh уму непостижимо ....
@S.Lott: "" "Я не думаю, что число особенно важно, так как Python будет иметь тенденцию правильно упаковываться без него." "" -1 . Не думай; исследовать. Без числа означает просто, что число по умолчанию равно 1. Имеет тенденцию упаковывать правильно ??? Возможно, вы думаете, что struct.pack("s", foo)
работает так же, как "%s" % foo
? Это не так; docs say "" " Для символа формата 's' число интерпретируется как размер строки, а не число повторений, как для других символов формата, например, 10s означает одну 10-байтовую строку, в то время как '10c' означает 10 символов. Для упаковки строка усекается или дополняется нулевыми байтами, в зависимости от ситуации."" "
@ Брендан: -1 . value
не является массивом (что бы это ни было); очевидно, что она явно должна быть строкой в юникоде ... вот здесь: value.encode("UTF8")
@ Мэтт Эллен: Строка кода, которую вы цитируете, сильно нарушена. Если в value
есть какие-либо не-ASCII символы, данные будут потеряны.
Давайте разберемся:
`struct.pack("<ii%ds"%len(value), ParameterTypes.String, len(value), value.encode("UTF8"))`
Уменьшите проблемное пространство, удалив первый элемент
struct.pack("<i%ds"%len(value), len(value), value.encode("UTF8"))
Теперь давайте предположим, что value
равно u'\xff\xff'
, поэтому len(value)
равно 2.
Пусть v8
= value.encode('UTF8')
, т.е. '\xc3\xbf\xc3\xbf'
.
Обратите внимание, что len(v8)
равно 4. Пенни уже понизилась?
Итак, теперь у нас есть
struct.pack("<i2s", 2, v8)
Число 2 упаковано как 4 байта, 02 00 00 00
. 4-байтовая строка v8
обрезается (длиной 2 в «2s») до длины два. ПОТЕРИ ДАННЫХ. СБОЙ.
Правильный способ сделать то, что, по-видимому, требуется:
v8 = value.encode('UTF8')
struct.pack("<ii%ds" % len(v8), ParameterTypes.String, len(v8), v8)