I've got a C DLL that exposes a handful of methods that return void pointers to a Class like so:
void *GetLicense() {
static AppLicenseImpl ipds_;
return (void *) &ipds_;
}
In C++, after loading the DLL, I'd do this to work with it:
typedef void *(* FPGetLicense)();
GetLicense_ = (FPGetLicense)GetAddress("GetLicense");
license_ = (AppLicense *) GetLicense_();
license_->GetApplicationStatus(); // Load data so that other calls don't fail
I can't figure out how to parallel that in Python. This gets me the pointer:
d = ctypes.cdll.LoadLibrary('license.dll')
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense() # returns ptr loc, something like 8791433660848L
But I obviously can't call p.GetApplicationStatus() in Python. Does anyone have a suggestion on how I'd instantiate that Class the rest of the way in Python so that I can call GetApplicationStatus()?
GetLicensereturns—at least it had better be, or the next line of C++ is going to segfault.AppLicenseclass in the c/c++ code?AppLicenseclass. On top of that, there is no real portable way to reference C++ types from a .DLL/.so in C++ in the first place; this is why you generally haveextern "C"wrappers that take a struct or void* as the first argument in the first place. But if you want to access members of a struct or class fromctypes, then yes, you need to define actypes.Struct. If you don't want to do that, consider usingcffior building custom bindings (possibly withCython) instead of usingctypes.AppLicensea subclass ofc_void_p. Then the instanceselfis a pointer to the C++ object. Add methods that wrap theextern "C"stubs that call the C++ methods. Add a_check_retval_method to centralize error checking the class when it's used as arestype.extern "C"function such asAppLicense_GetApplicationStatusthat takes anAppLicense *and calls theGetApplicationStatusmethod. The PythonAppLicenseclass (a subclass ofc_void_p) has aGetApplicationStatusmethod that callsd.AppLicense_GetApplicationStatus(self). You'd setd.GetLicense.restype = AppLicense, etc. As abarnert mentioned, you may want to look into alternatives for wrapping C++ libraries such as Boost.Python or SWIG.