When Importing c.dll
to python using ctypes
, and iostream
has been included in a.cpp
, I encounter the following error:
Could not find module 'C:\Test\foo.dll' (or one of its dependencies).
Try using the full path with constructor syntax.
As explained at bugs.python.org this is an ambiguous error, indicative of a deeper issue.
A few quick notes to be thorough:
exists(path)
reveals as much.istream
, ostream
, and cmath
all link without issue.iostream
, the only file that iostream
includes other than istream
and ostream
is bits/c++config.h
. However, cmath
also includes bits/c++config.h
and I am still able to load the .dll
in python
with cmath
included.3.10.8
extern "C"__declspec(dllexport)
instead of extern "C"
g++
from mingw64
iostream
.The contents of my files for reproduction is as follows:
a.cpp
#include <ostream>
extern "C" void Print()
{
printf("Hello!");
}
b.py
from ctypes import *
core = cdll.LoadLibrary("C:/Test/c.dll")
core.Print()
makefile
main:
g++ -shared -o .c.dll .a.cpp
python3 -B b.py
If I compile this using make
it works perfectly, as it should.
However, if I change a.cpp
to the following and compile, I receive the above noted error:
a.cpp
#include <iostream>
extern "C" void Print()
{
printf("Hello!");
}
As far as I can tell, the linker cannot find a dependency that I cannot see in the mingw64
version of iostream
, but that is as much as I can discern.
Does anyone else encounter this error using the above files? Any thoughts?
at this moment for python 3.10 the solution for this is to statically link against both libgcc
and libstdc++
(or copy them from mingw/bin folder to your dll folder), this doesn't seem to be the case for versions of python prior to 3.10
g++ -shared -o c.dll a.cpp -static-libstdc++ -static-libgcc
it seems like python 3.10 currently doesn't look for those dlls in your PATH
.
Edit: according to this stack overflow answer, you have to add the dlls path manually using os.add_dll_directory
, alternatively you can use CDLL winmode
parameter to allow windows to search for dlls in your PATH, but it is discouraged, and linking them statically is the best solution to run the dll on systems that don't have mingw installed or on PATH.
core = CDLL(r"c.dll",winmode=0x8)