Lluís Alemany-Puig
Lluís Alemany-Puig

Reputation: 1243

Problems with C++, Python 3.7.4, SWIG 4.0.0 and Windows 10 - ModuleNotFoundError

I'm writing a library in C++ that is to be published soon. In addition to the library, I've added an interface to Python 3.7.4 that is automatically generated using SWIG 4.0.0. In Ubuntu 18.04, the interface works perfectly: it can be imported into Python3 without any problem. In Windows 10, however this is not the case. After generating the wrapper in C++, compiling it, and linking it against the compiled C++ library (as a shared object), into a *.so file, importing it from python does not work. The error message after doing import is similar to the following

     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       File "C:\programming\python_lib\lal.py", line 15, in <module>
         import _lal
     ModuleNotFoundError: No module named '_lal'

I do not understand why this error message shows up. The installation of python works well (I can import its typical packages, like sys) and I can execute python scripts using the command terminal. I was hoping that you could help me with this.

I would like to add that this also happens with the most minimal example that I could come up with:

    int my_factorial(int n);
    #include "fact.hpp"
    int my_factorial(int n) {
        if (n == 0) { return 1; }
        return n*my_factorial(n - 1);
    }
    %module factorial
    %{
    #include "fact.hpp"
    %}
    %include "fact.hpp"
    PYTHON_INCLUDE = -IC:/programming/Python37/include
    all: factorial.so 
    factorial.so: fact.o wrap_factorial.o
        g++ -o $@ -shared $<
    wrap_factorial.o: wrap_factorial.cpp
        g++ -o $@ -c $< $(PYTHON_INCLUDE)
    fact.o: fact.cpp fact.hpp
        g++ -c fact.cpp
    wrap_factorial.cpp: factorial.i fact.hpp
        swig -c++ -python -py3 -o wrap_factorial.cpp factorial.i

The error message that python gives me, regardless of the directory that I launch python in, is:

     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       File "C:\Users\Usuari\factorial.py", line 15, in <module>
         import _factorial
     ModuleNotFoundError: No module named '_factorial'

I would very much appreciate it if some of you could help me on how to solve this problem. I've searched the site before but without success.

Thanks in advance to you all.


Other, possibly useful, details:

Upvotes: 3

Views: 1398

Answers (1)

Llu&#237;s Alemany-Puig
Llu&#237;s Alemany-Puig

Reputation: 1243

Thank you @flexo for pointing out the problem. On Windows, we have to make a .pyd, not a .so.

Besides the changes pointed out by @Flexo, there are other things that have to be changed too. The minimal example's Makefile correct version is:

    PYTHON_INCLUDE  = -IC:\programming\Python37\include
    PYTHON_LIBS_DIR = -LC:\programming\Python37\libs
    all: _factorial.pyd
    _factorial.pyd: fact.o wrap_factorial.o
        g++ -o $@ -shared fact.o wrap_factorial.o $(PYTHON_LIBS_DIR) -lpython3 $(PYTHON_LIBS_DIR) -lpython37
    wrap_factorial.o: wrap_factorial.cpp
        g++ -o $@ -c $< $(PYTHON_INCLUDE)
    fact.o: fact.cpp fact.hpp
        g++ -c fact.cpp
    wrap_factorial.cpp: factorial.i fact.hpp
        swig -c++ -python -py3 -o wrap_factorial.cpp factorial.i

Note the changes: - Use underscore at the beginning of the module's name (something I should've known). - Link against both python37 and python3 (the second does most of the job, but the two are required).

Again, thanks to @flexo for pointing out the most important problem.

Upvotes: 4

Related Questions