PYthon ctypes «Ошибка типа» Экземпляр LP_LP_c_long вместо _ctypes.Пикпоинтертип

#python #dll #arguments #ctypes

Вопрос:

Я пытаюсь использовать библиотеку dll, написанную на C . У него есть эта функция:

 bool PMDllWrapperClass::GetDeviceList(DEVICE** pDeviceArray, int* nDeviceCount, LAN_DEVICE** pLanDeviceArray, int LanDeviceCount, int InterfaceTypeToSearch)
 

Я пытался:

 cP = ctypes.POINTER(ctypes.POINTER(ctypes.c_int64))
cIP = ctypes.POINTER(ctypes.c_int32)
cLP = ctypes.POINTER(ctypes.c_int32)
cDC = ctypes.c_int32()
cIS = ctypes.c_int32()


resultgetdev = PMDll.GetDeviceList(cP, cIP, cLP, cDC, cIS)
 

Но там написано:

 ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_LP_c_long instance instead of _ctypes.PyCPointerType
 

Я также попытался использовать двойной указатель, но это не сработало. Могу ли я решить эту проблему с помощью ctypes или это невозможно?

Комментарии:

1. Каковы определения DEVICE и LAN_DEVICE ? Вам также необходимо передавать экземпляры типов, а не типов , и вы должны объявить .argtypes и .restype . ctypes также понимает только интерфейс C , поэтому GetDeviceList функция должна быть extern "C" .

Ответ №1:

Сообщение об ошибке связано с передачей типов вместо экземпляров. Вы должны объявить типы аргументов и возвращаемый тип, чтобы типы ctypes могли дважды проверить правильность переданных значений.

Для этого требуется дополнительная информация, чтобы быть точной, но минимум, который вам нужен, — это:

test.cpp

 #ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

struct DEVICE;
struct LAN_DEVICE;

extern "C" __declspec(dllexport)
bool GetDeviceList(DEVICE** pDeviceArray, int* nDeviceCount, LAN_DEVICE** pLanDeviceArray, int LanDeviceCount, int InterfaceTypeToSearch) {
    return true;
}
 

test.py:

 from ctypes import *

class DEVICE(Structure):
    _fields_ = () # members??

class LAN_DEVICE(Structure):
    _fields_ = () # members??

dll = CDLL('./test')
dll.GetDeviceList.argtypes = POINTER(POINTER(DEVICE)), POINTER(c_int), POINTER(POINTER(LAN_DEVICE)), c_int, c_int
dll.GetDeviceList.restype = c_bool

device_list = POINTER(DEVICE)()     # create instances to pass by reference for output(?) parameters
landev_list = POINTER(LAN_DEVICE)()
dev_count = c_int()

lan_count = 5    # ??
search_type = 1  # ??

result = dll.GetDeviceList(byref(device_list),byref(dev_count),byref(landev_list),lan_count,search_type)