I am trying to bind C with Python on Windows using SWIG and MinGW-w64 g . So far I got a factorial calculator function in C :
// factorial.cpp
long fact(long num)
{
if (num <= 1) return 1;
return num * fact(num - 1);
}
This is my factorial.i:
%module factorial
%{
extern long fact(long num);
%}
extern long fact(long num);
I then use Command Prompt to build these:
swig -python -c factorial.i
This generates factorial_wrap.cxx and factorial.py. I then use MinGW-w64 g to build these:
g -c factorial.cpp
g -c -fpic factorial_wrap.cxx -IC:\Users\kritomas\AppData\Local\Programs\Python\Python38\include
g factorial.o factorial_wrap.o -LC:\Users\kritomas\AppData\Local\Programs\Python\Python38\libs -shared -lpython38 -o _factorial.pyd
So far no problem. The problem occurs when I then open up Python in Command Prompt and try to import these:
C:\Users\kritomas\Desktop>python
Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import factorial
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\kritomas\Desktop\factorial.py", line 15, in <module>
import _factorial
ImportError: DLL load failed while importing _factorial: The specified module could not be found.
>>>
Here's the error, as you can see above. I already tried Dependency Walker, that gave me 2 missing DLLs. After putting both of them into System32, it still happens. I already tried using extern "C" instead of extern:
%module factorial
%{
extern "C" long fact(long num);
%}
extern "C" long fact(long num);
It just straight up removes fact():
C:\Users\kritomas\Desktop>g factorial.o factorial_wrap.o -LC:\Users\kritomas\AppData\Local\Programs\Python\Python38\libs -shared -lpython38 -o _factorial.pyd
factorial_wrap.o:factorial_wrap.cxx:(.text 0x38d7): undefined reference to `fact'
collect2.exe: error: ld returned 1 exit status
I have the same issue with Python 3.9.7, the only reason why I downgraded to 3.8.10 is because it runs perfectly on my Linux Mint VM (which has Python 3.8.10), if instead of running:
g -c -fpic factorial_wrap.cxx -IC:\Users\kritomas\AppData\Local\Programs\Python\Python38\include
g factorial.o factorial_wrap.o -LC:\Users\kritomas\AppData\Local\Programs\Python\Python38\libs -shared -lpython38 -o _factorial.pyd
I run:
g -c -fpic factorial_wrap.cxx -I/usr/include/python3.8
g factorial.o factorial_wrap.o -shared -o _factorial.so
It works perfectly:
kritomas@kritomas-virtual-machine:~/Desktop$ python
Python 3.8.10 (default, Sep 28 2021, 16:10:42)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import factorial
>>> factorial.fact(5)
120
What am I doing wrong? Is there anything I am missing here? Please help me. Thanks in advance ;)
CodePudding user response:
I met exactly the same problem after upgraded python to 3.9 on windows . After struggling for hours, I managed to solve it by manually copying some dlls from ***/mingw/bin/ where mingw32-g is found to where my ***.pyd is located. I'm sure that ***/mingw/bin/ has been appended to %PATH%, but don't know why python3.9 couldn't find it.