Форум сайта python.su
Есть задача подключить dll для управления прибором. Но в процессе реализации возникли сложности.
from ctypes import * from ctypes.wintypes import * class dmQWORD(Structure): _fields_ = [ ('deviceType', DWORD), ('deviceID', DWORD) ] class devModel(Structure): _fields_ = [ ('dmQWORD', POINTER(dmQWORD)), ('dmChar', CHAR * 8) ] class AULDEVIDN(Structure): _fields_ = [ ("interface_type", INT), ('id', DWORD), ('devModel', POINTER(devModel)), ('sn', BYTE * 16), ('tag', DWORD), ('HWDate', DWORD), ('HWVers', DWORD), ('PLISVers', DWORD), ('dwReserved', DWORD), ('deviceName', CHAR * 16) ] TANetInterface = { 'aniUnknown': INT(-1), 'aniAUN': INT(0), 'ainAUN2': INT(1), 'aniALAN': INT(2), 'aniAEPP': INT(3), 'aniAVCOM': INT(4), 'aniAUXPR': INT(5), 'aniCH372': INT(6), 'aniUOWRI': INT(7), 'aniULAN': INT(8)} #Тип интерфейса для связи socketIndex = INT(-1) #(int)Индекс сокета устройства, -1 - сканировать все AULInterface = TANetInterface['aniUnknown'] #Тип интерфейса для связи deviceList = AULDEVIDN() listSize = INT(1) #(int)Размер списка переданного от функции needSize = INT() #(int)Возвращает количество обнаруженных устройств mydll = cdll.LoadLibrary("APS7315.dll") ScanSocket = mydll.APS7315_ScanSocket ScanSocket.restype = INT ScanSocket.argtypes = [INT, INT, AULDEVIDN, INT, INT] ScanSocket(socketIndex, AULInterface, byref(deviceList), listSize, byref(needSize))
ViStatus APS7315_ScanSocket (int socketIndex, TANetInterface AULInterface, AULDEVIDN *deviceList, int listSize, int *needSize);
Описание
Создает список всех доступных по технологии AULNet устройств на указанном сокете (параметр Socket Index) по указанному интерфейсу (AUL Interface).
Список параметров
socketIndex
Variable Type int
Индекс сокета, устройства на котором вы хотите обнаружить. Передайте здесь -1, чтобы сканировать весь список сокетов.
Величина по умолчанию: -1
AULInterface
Variable Type TANetInterface
Тип интерфейса, используемый для связи с AUL-устройством.
Определение типа:
/* Тип интерфейса */
typedef enum tagANetInterface {
aniUnknown =-1, /* неизвестный */
aniAUN = 0, /* стандартный драйвер AUNUSB */
aniAUN2, /* драйвер AUNUSB 2 */
aniALAN, /* драйвер AUNLAN */
aniAEPP, /* драйвер EPP-порта */
aniAVCOM, /* виртуальный COM-порт */
aniAUXPR /* USB Xpress */
} TANetInterface;
Передайте здесь aniUnknown (-1), чтобы сканировать весь список сокетов.
Величина по умолчанию: -1
deviceList
Variable Type AULDEVIDN (passed by reference)
указатель на заполняемый список найденных устройств. Список составляется из структур AULDEVIDN (размер структуры 56 байт), определенной следующим образом:
/* идентификационный блок AUL-устройства */
typedef struct tagAULDEVIDN
{
TANetInterface interface_type; // тип интерфейса
DWORD id; // идентификатор (индекс локального подключения)
union {
struct {
DWORD deviceType; // Идентификатор типа прибора
DWORD deviceID; // Идентификатор номера прибора
} dmDWORD;
LONGLONG dmQWORD; // Тип модели в виде 64-битного целого
char dmChar; // Тип модели в виде 8-символьной строки
} devModel;
BYTE sn; // строка серийного номера
DWORD tag; // используется по необходимости программистом
DWORD HWDate; //дата прошивки (в формате 0xDDMMYYYY)
DWORD HWVers; //версия прошивки (в формате 0xMaMiReBl)
DWORD PLISVers; //версия PLIS
DWORD dwReserved; //зарезервировано
} AULDEVIDN;
listSize
Variable Type int
Показывает размер переданного на заполнение списка описаний устройств (параметр Device List). Если выделенный размер не достаточен для описания всех обнаруженных при заданных условиях устройств, то список заполняется насколько возможно, а нужное число записей для полного списка возвращается в параметре Need Size.
needSize
Variable Type int (passed by reference)
Показывает количество обнаруженных при заданных условиях устройств.
Возвращаемое значение
Возвращается код ошибки, в случае успеха - EAPS7315_NO_ERROR. Для получения дополнительной информации воспользуйтесь функциями GetErrorMessage или error_message.
Имя события проблемы: APPCRASH
Имя приложения: python.exe
Версия приложения: 3.6.150.1013
Отметка времени приложения: 585cd094
Имя модуля с ошибкой: python36.dll
Версия модуля с ошибкой: 3.6.150.1013
Отметка времени модуля с ошибкой: 585ccfcd
Код исключения: c0000005
Смещение исключения: 000b81a9
Версия ОС: 6.1.7601.2.1.0.256.48
Код языка: 1049
Дополнительные сведения 1: 0a9e
Дополнительные сведения 2: 0a9e372d3b4ad19135b953a78882e789
Дополнительные сведения 3: 0a9e
Дополнительные сведения 4: 0a9e372d3b4ad19135b953a78882e789
Отредактировано MaximBMT (Авг. 9, 2017 16:40:17)
Офлайн
MaximBMTViStatus APS7315_ScanSocket (int socketIndex, TANetInterface AULInterface, AULDEVIDN *deviceList, int listSize, int *needSize);
MaximBMTНе соответствуют типы. Там два указателя и в ctypes.wintypes есть соотвествующие типы.ScanSocket.argtypes = [INT, INT, AULDEVIDN, INT, INT]
Отредактировано py.user.next (Авг. 10, 2017 04:57:37)
Офлайн
py.user.next спасибо за помощь. Тип указателя на int там есть, а вот указателя на структуру я там не нашел, да и не должно быть. Это должно быть что-то типа POINTER(AULDEVIDN) (в моем случае). Он ругается на несоответствие типов ValueError: Procedure called with not enough arguments (20 bytes missing) or wro
ng calling convention (если я правильно его понял).
И если я правильно понимаю то, “.argtypes” это что-то типа прототипа функции. Как бы если типы не соответствуют, то питон начинает ругаться. А он у меня не ругается, а просто крашиться.
Я попробовал изменить тип последнего аргумента в “.argtypes” на PINT - результат тот-же
Отредактировано MaximBMT (Авг. 10, 2017 14:18:47)
Офлайн
MaximBMT, насколько я помню, если ты при вызове делаешь byref(deviceList) то в argtypes нужно использовать POINTER(AULDEVIDN) тоже со свторым параметром типа INT.
Както так:
ScanSocket.argtypes = [INT, INT, POINTER(AULDEVIDN), INT, POINTER(INT)] ScanSocket(socketIndex, AULInterface, byref(deviceList), listSize, byref(needSize))
[code python][/code]
Офлайн
PEHDOM, спасибо большое. Но он так выдает ошибку ValueError: Procedure called with not enough arguments (20 bytes missing) or wro ng calling convention. Как я понял типы не соответствуют.
Может есть еще идеи?
Офлайн
Интересно получается если через print вывести типы
в arguments
<class ‘ctypes.c_long’>, <class ‘ctypes.c_long’>, <class ‘__main__.LP_AULDEVIDN’>, <class ‘ctypes.c_long’>, <class ‘ctypes.wintypes.LP_c_long’>
в функции
<class ‘ctypes.c_long’> <class ‘ctypes.c_long’> <class ‘CArgObject’> <class ‘ctypes.c_long’> <class ‘CArgObject’>
Офлайн
Думал может в Питоне глюк (всяко бывает). Запускал через 3.6 и 2.6 никакой разницы.
Офлайн
Э-э-э вам же в качестве аргумента нужно подавать список структур, а вы подаете структуру.Даже если вы хотите получить 1 результат, нужно структуру в список из одного элемента запихнуть.
насколько я помню както так кажись это делается:
deviceList = (AULDEVIDN()*1)()
[code python][/code]
Отредактировано PEHDOM (Авг. 10, 2017 20:17:42)
Офлайн
PEHDOM по идее и будет 1 устройство. argtype принимает и не ругается AULDEVIDN*1. Но это, к сожалению, все равно не работает. питон ругается на то, что * не поддерживает подобные операнды.
Если я правильно понимаю, то цифра после звездочки определяет массив однотипных данных. То есть количество резервируемого места и по идее не должно быть никакой разницы есть там *1 или нет.
Но есть предположение что функция выдает слишком много данных а python столько не зарезервирвал. Т.е. я не правильно распределил память (предположительно не верно построил структуру AULDEVIDN) и си-шная функция пытается записать данные в область памяти которая для нее не зарезервированна. И из-за попытки обращения не к своему участку памяти wind'а завершает python.
Отредактировано MaximBMT (Авг. 17, 2017 16:57:58)
Офлайн
MaximBMTДа честно говоря я не знаю как там внутри вашей ДЛЛ идет обращение к элементам массива, но обычно если вы ожидаете список обьектов, а получаете обьект то у вас программа выдаст ошибку . Что в пайтоне что в Си синтаксис доступа к элемнтам спика весьма похож. Попробуйте на досуге.
Если я правильно понимаю, то цифра после звездочки определяет массив однотипных данных. То есть количество резервируемого места и по идее не должно быть никакой разницы есть там *1 или нет.
[code python][/code]
Отредактировано PEHDOM (Авг. 17, 2017 23:03:16)
Офлайн