3

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?

leoluk
  • 12,561
  • 6
  • 44
  • 51
  • No, unless something changed recently in ctypes, it indeed does not support C++. http://stackoverflow.com/a/145649/477878 has a workaround, but may be tedious if you don't have the original headers. – Joachim Isaksson Aug 07 '12 at 21:10
  • Have you looked at [Cython](http://www.cython.org/)? I feel pretty confident it can link statically with a C++ library. – Josiah Aug 07 '12 at 21:12
  • Yes, I do a lot of work in Cython, but without header files, this seems rather difficult. – leoluk Aug 07 '12 at 21:16
  • Cant you look up the address of the function through os apis and then cast it to a function pointer? Im not quite sure how __thiscall behaves on constructors but if am i right youll have to pass it a fresh allocated memory block of the objects size. – Sebastian Hoffmann Aug 07 '12 at 21:16
  • 2
    @leoluk You don't actually need header files (though I don't know how they expect anyone to use it without a header file), any API reference will do. If you have an API reference, you can write your own header file that will just implement the parts you need. – Josiah Aug 07 '12 at 21:18
  • @Josiah In case certain members are unknown one can insert placeholders like `unsigned char unk1[16]` guranteing that known members after this unknown region can be accessed normally. – Sebastian Hoffmann Aug 07 '12 at 21:21
  • They did not expect anyone to use it, this is the problem (complete lack of documentation), and the company vanished. The DLL controls video capture hardware using a strange UDP protocol (hard to reverse-engineer), and I want to implement my own client. – leoluk Aug 07 '12 at 21:25
  • Apparently, [this patch](https://code.google.com/p/ctypes-stuff/source/browse/trunk/ctypes-cpp/README) adds support for `__thiscall` to ctypes. This might be exactly what I've been looking for. – leoluk Aug 07 '12 at 21:33
  • If you know how to call the functions and what they return, you know all you need to make a small header file to use for a Cython extension. – Josiah Aug 07 '12 at 21:36

0 Answers0