Как вы можете получить значения char от не ascii персонажа - PullRequest
1 голос
/ 17 октября 2019

Здравствуйте, у меня есть строка в языке Python POINTER(wintypes.BYTE) Я использую DATA_BLOB в языке Python (

class CREATE_DATA_BLOB(Structure):
    _fields_ = [('cbData', wintypes.DWORD), ('pbData', POINTER(wintypes.BYTE))]

), поэтому у меня есть DLL, которая шифрует данные. после шифрования данных данные сохраняются в pbData структуры data_blob. Проблема в том, что значения внутри pbData (например, pbData[0]) содержат -42, например, некоторые из них находятся в диапазоне от 0 до 255 - они хороши, но некоторые являются совершенно случайными числами, и я не могувыяснить, как превратить эти не-ASCII числа в символ. В c ++ я использую функцию writeFile и просто отправляю pbData, и все отлично работает в python. Дело не в том, что у меня возникает эта ошибка, если я пытаюсь записать pbData в текстовый файл:

file.write(data_out.pbData)
TypeError: write() argument must be str, not LP_c_byte

Я действительно не знаю, как решить эту проблему.

1 Ответ

2 голосов
/ 17 октября 2019

Листинг [Python 3.Docs]: ctypes - библиотека сторонних функций для Python .

Существует несколько проблем:

  • wintypes.BYTE isподписано ( [Python.Bugs]: неправильный тип для wintypes. БАЙТ )
  • file.write работает со Python строками (в вашем случае), а не ctypes указатели (и между ними нет неявного преобразования)
  • Идем дальше (это появится после решения других 2): в вашем буфере "специальные" char s. Это означает, что вы не должны рассматривать это как «нормальную строку», а как двоичную последовательность (в противном случае вы можете получить ошибки кодирования / декодирования). Как следствие, откройте файл, в который вы хотите выгрузить его содержимое, в двоичном режиме (например: file = open(file_name, "wb")).
>>> import ctypes as ct
>>> from ctypes import wintypes as wt
>>>
>>> class CREATE_DATA_BLOB(ct.Structure):
...     _fields_ = [
...             ("cbData", wt.DWORD),
...             ("pbData", ct.POINTER(ct.c_ubyte)),  # wt.BYTE is signed !!!
...     ]
...
>>>
>>> buf_initial = b"AB\xD6CD\xD9EF\x9CGH"  # Contains the 3 chars you mentioned
>>> buf_initial
b'AB\xd6CD\xd9EF\x9cGH'
>>> # Populate the structure as it was done from C++
...
>>> blob = CREATE_DATA_BLOB(len(buf_initial), ct.cast(ct.create_string_buffer(buf_initial), ct.POINTER(ct.c_ubyte)))
>>> blob.cbData, blob.pbData
(11, <__main__.LP_c_ubyte object at 0x00000154FF6998C8>)
>>>
>>> buf_final = bytes(blob.pbData[:blob.cbData])  # Convert the pointer explicitly to Python bytes
>>> buf_final
b'AB\xd6CD\xd9EF\x9cGH'
>>> buf_initial == buf_final
True
>>>
>>> with open("q058436070_out.bin", "wb") as file:
...     file.write(buf_final)
...
11
...