У меня есть C DLL, которая предоставляет несколько методов, которые возвращают void pointers
в класс следующим образом:
void *GetLicense() {
static AppLicenseImpl ipds_;
return (void *) &ipds_;
}
В С++ после загрузки DLL я бы сделал это, чтобы работать с ней:
typedef void *(* FPGetLicense)();
GetLicense_ = (FPGetLicense)GetAddress("GetLicense");
license_ = (AppLicense *) GetLicense_();
license_->GetApplicationStatus(); // Load data so that other calls don't fail
Я не могу понять, как сделать это параллельно в Python. Это дает мне указатель:
d = ctypes.cdll.LoadLibrary('license.dll')
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense() # returns ptr loc, something like 8791433660848L
Но я, очевидно, не могу вызвать p.GetApplicationStatus()
в Python. Есть ли у кого-нибудь предложение о том, как я могу создать экземпляр этого класса в Python, чтобы я мог вызывать GetApplicationStatus()
?
GetLicense
возвращается — по крайней мере, так должно быть, иначе следующая строка C++ приведет к segfault. - person abarnert   schedule 15.10.2013AppLicense
в коде c/c++? - person g.d.d.c   schedule 15.10.2013AppLicense
. Вдобавок ко всему, нет реального переносимого способа ссылаться на типы C++ из .DLL/.so в C++; вот почему у вас обычно естьextern "C"
оболочки, которые принимают struct или void* в качестве первого аргумента в первую очередь. Но если вы хотите получить доступ к членам структуры или класса изctypes
, тогда да, вам нужно определитьctypes.Struct
. Если вы не хотите этого делать, рассмотрите возможность использованияcffi
или создания пользовательских привязок (возможно, с помощьюCython
) вместо использованияctypes
. - person abarnert   schedule 16.10.2013AppLicense
подклассомc_void_p
. Тогда экземплярself
является указателем на объект C++. Добавьте методы, которые заключают в себе заглушкиextern "C"
, вызывающие методы C++. Добавьте метод_check_retval_
для централизованной проверки ошибок класса, когда он используется какrestype
. - person Eryk Sun   schedule 16.10.2013self
в моем классе, ссылающееся на указатель. - person g.d.d.c   schedule 16.10.2013extern "C"
, такую какAppLicense_GetApplicationStatus
, которая принимаетAppLicense *
и вызывает методGetApplicationStatus
. Класс PythonAppLicense
(подклассc_void_p
) имеет методGetApplicationStatus
, который вызываетd.AppLicense_GetApplicationStatus(self)
. Вы бы установилиd.GetLicense.restype = AppLicense
и т. д. Как уже упоминал Абарнерт, вы можете изучить альтернативы для обертывания библиотек C++, таких как Boost.Python или SWIG. - person Eryk Sun   schedule 16.10.2013