#python #delphi #dll #ctypes
Есть Dll(исходников нету), есть интерфейсный модуль к ней написанный на Delphi. Вызываю функцию: function ProcessBonusListCountersPrint(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; stdcall; type TBonusCountersPrintQuery = packed record Card: array[0..15] of char; type TListCountersPrint = packed record Lines: array[0..PACKET_COUNTERS_PR_MAX_LINE_COUNT - 1] of TCounterLine; type TCounterLine = packed record LineNo: word; IsLast: byte; Num_Counter: word; N_Counter: array[0..9] of char; Value_Counter: Cardinal; (Описание структур, функций беру из интерфейса) На Python реализовал так: from ctypes import * class TBonusCountersPrintQuery(Structure): _fields_ = [("Card", c_char * 15)] class TListCountersPrint(Structure): _fields_ = [("Lines", TCounterLine * 20)] class TCounterLine(Structure): _fields_ = [("LineNo", c_int), ("IsLast", c_byte), ("Num_Counter", c_int), ("N_Counter", c_char * 11), ("Value_Counter", c_int)] packet_counters_pr_max_line_count = 20; i = 0; ProcessBonusListCountersPrint = libc.ProcessBonusListCountersPrint ProcessBonusListCountersPrint.argtype = [TBonusCountersPrintQuery, POINTER(TListCountersPrint)] ProcessBonusListCountersPrint.restype = c_int32 vBonusCountersPrintQuery = TBonusCountersPrintQuery() vBonusCountersPrintQuery.Card = b'123456798' vListCountersPrint = TListCountersPrint() res = ProcessBonusListCountersPrint(vBonusCountersPrintQuery, byref(vListCountersPrint)) print('ProcessBonusListCountersPrint', res) for i in range(packet_counters_pr_max_line_count): if vListCountersPrint.Lines[i].IsLast == 1: break print(vListCountersPrint.Lines[i].Num_Counter, vListCountersPrint.Lines[i].N_Counter.decode('cp1251'), vListCountersPrint.Lines[i].Value_Counter) vListCountersPrint.Lines[i].N_Counter - возвращается правильное значение, а вот числовые значения из этой структуры все неверные. Числовые типы все пробовал, ни один не дал даже похожего результата. Вопрос: как получить нужные мне данные?(в среде Borland Delphi 7 все работает)
Ответы
Ответ 1
Структуры в Python надо объявлять с параметром _pack_ = 1, поскольку в Delphi они объявлены как packed. Неправильно объявлены поля Card (15 байт, хотя в Delphi - 16) и N_Counter (11 байт, хотя в Delphi - 10). В структуре TCounterLine в Python использованы неправильные типы для LineNo и Value_Counter (в Delphi word - это 2-х байтовое беззнаковое целое, в ctypes для этого есть тип c_ushort).Ответ 2
Совместил ответ от zed и tonal. В итоге получилась такая структура: class TCounterLine(Structure): _pack_ = 1 _fields_ = [("LineNo", c_short), ("IsLast", c_byte), ("Num_Counter", c_short), ("N_Counter", c_char * 10), ("Value_Counter", c_int)] Всё заработало. Большое спасибо за помощь)Ответ 3
Вот так будет правильно: class TCounterLine(Structure): _fields_ = [("LineNo", c_short), # LineNo: word; ("IsLast", c_byte), # IsLast: byte; ("Num_Counter", c_short), # Num_Counter: word; ("N_Counter", c_char * 10), # N_Counter: array[0..9] of char; ("Value_Counter", c_int)] # Value_Counter: Cardinal;
Комментариев нет:
Отправить комментарий