Python ctypes and DLL that uses a COM object

com, ctypes, dll, python

Solution

You could use something like processexplorer to find out if all the required libraries are loaded into the running process.

- Did you initialize the COM runtime somewhere in your Python code? In your C++ code? One difference between C++ code and Python/ctypes is that in the C++ code the dll's DllMain() function is called when the dll is loaded, Python/ctypes doesn't do this because of the fully dynamic loading of the dll.

Problem

Under Windows, I'm trying to use a 3rd party DLL (`SomeLib.dll`) programmed in C++ from Python 2.7 using `ctypes`. For some of its features, this library uses another COM DLL (`SomeCOMlib.dll`), which itself uses other DLL (`LibA.dll`). Please note that this isn't about using a COM DLL directly from Python, but it's about using a DLL that uses it from Python. To make the integration with Python easier, I've grouped the calls I want to use into my own functions in a new DLL (`MyLib.dll`), also programmed in C++, simply to make the calls from `ctypes` more convenient (using `extern "C"` and tailoring the functions for specific scenarios). Essentially, my library exposes 2 functions: `doSomethingSimple()`, `doSomethingWithCOMobj()` (all returning `void`, no parameters). The "effective" dependency hierarchy is as follows: ``` MyLib.dll SomeLib.dll SomeCOMlib.dll LibA.dll ``` I'm able to write a simple C++ console application (Visual C++) that uses `MyLib.dll` and makes those 2 consecutive calls without problem. Using Python/ctypes, the first call works fine, but the call that makes use of COM throws a `WindowsError: [Error -529697949] Windows Error 0xE06D7363`. From the rest of the library behaviour, I can see that the problem comes exactly where that COM call is made. (The simple test C++ application also fails more or less at the same place if `LibA.dll` is missing, but I'm not sure if it's related.) I've looked at the dependency hierarchy using Dependency Walker. `SomeCOMlib.dll` isn't listed as a dependency of `SomeLib.dll`, although it's clearly required, and `LibA.dll` isn't listed as a dependency of `SomeCOMlib.dll`, although it's also clearly required at run time. I'm running everything from the command line, from within the directory where these DLLs are (and the C++ sample executable works fine). I've tried to force the PATH to include that directory, and I've also tried to copy the DLLs to various places where I guessed they might be picked up (`C:\Windows\System32` and `C:\Python27\DLLs`), without success. `SomeCOMlib.dll` was also registered with `regasm.exe`. What could cause this difference between using this DLL from a plain C++ application and from Python's `ctypes` when it comes to its own usage of the COM mechanism (and possibly the subsequent loading of other DLLs there)? Which steps would give at least a bit more information than `Windows Error 0xE06D7363` from Python, to be able to investigate the problem further? The Python code looks like this: ``` import ctypes myDll = ctypes.WinDLL("MyLib.dll") myDll.doSomethingSimple() myDll.doSomethingWithCOMobj() # This statement throws the Windows Error ``` (The test C++ standalone application that works, linked to `MyLib.dll` makes exactly the same calls within `main`.)

Original source