I want to access a class in a closed-source DLL from Python, compiled with Visual C++. I have no header files, just the object code and no interface descriptions.
I can load the DLL using ctypes.CDLL
, but any attempt to call a function results in an access violation. Apparently ctypes doesn't know about the __thiscall
calling convention (it's not designed for C++ anyway). Usually, I'd simply write an extension module, but without source code I'm out of luck here.
This is what MSDN says:
The __thiscall calling convention is used on member functions and is the default calling convention used by C++ member functions that do not use variable arguments. Under __thiscall, the callee cleans the stack, which is impossible for vararg functions. Arguments are pushed on the stack from right to left, with the this pointer being passed via register ECX, and not on the stack, on the x86 architecture.
For example, this is how the exported function signature looks (unmangled):
public: __thiscall CFoo::CFoo(void)
My attempt to access the constructor from Python:
getattr(dll, "??0CFoo@@QAE@XZ")(c_voidp())
This doesn't work because ctypes doesn't pass the instance pointer, and all I get is an access violation.
I guess that I can't easily do this because ctypes has no C++ support, and as every compiler has its own name mangling conventions, it would be difficult to implement it in a generic way. The __thiscall
calling convention is not implemented by ctypes.
The obvious workaround would be a wrapper, written in Visual C++, which exports the function as __stdcall
, but I don't want to rely on this.
Correct? Or is there any trick I missed?