3

I am trying to call some of my C++ machine learning code in Python. I have tried multiple other methods, such as this question and this explanation, both of which are very similar. I followed these to the letter, with the same filenames and code.

For example, I have the following C++ code...

file.cpp

#include <iostream>

void some_code()
{
    std::cout << "Hello world!";
}

extern "C"
{
    void hello_there() { some_code(); }
}

I then compile it with...

g++ -c -fPIC file.cpp -o foo.o

g++ -shared -Wl,-soname,lib.so -o lib.so foo.o

code.py

from ctypes import cdll

lib = cdll.LoadLibrary('./lib.so')

lib.hello_there()
Traceback (most recent call last):
  File "c:\some-path-here\1 - calling-cpp-with-python.py", line 5, in <module>
    lib = cdll.LoadLibrary('./lib.so')
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\some-path-here\lib.so' (or one of its dependencies). Try using the full path with constructor syntax.

What am I doing wrong? I have also tried with compiling it to a DLL file, and adding __declspec(dllexport) before the "void" in the extern bit.

Additional Notes

If it is helpful...

  • I am on Windows 10
  • I am using the MinGW G++
  • The name of the directory with the files in has spaces in it.
  • This is running on Python 3.10, but the error also occurs in 3.9
SamTheProgrammer
  • 1,051
  • 1
  • 10
  • 28
  • 1
    You probably need to tell Python how to find the C++ standard library, because it is unlikely to be in a place where Python knows to look at. Can you compile a C++ *program* and the run it from a cmd window (not from a mingw shell)? If not, then it's the same problem you are seeing here. – n. m. could be an AI Feb 14 '22 at 17:11
  • 1
    You are using `.so` files in windows. I have doubt whether it will work or not, but probably WSL can help you. It looks like you have some path issue. – akm Feb 14 '22 at 17:11
  • 1
    You can try removing the `./` part and write it like `lib.so`. – akm Feb 14 '22 at 17:15
  • @akm, thanks, I do sometimes use WSL, so I shall try that. – SamTheProgrammer Feb 14 '22 at 19:18
  • However, I would still like to use Windows, to make my code cross-platform – SamTheProgrammer Feb 14 '22 at 19:24
  • @n.1.8e9-where's-my-sharem. I have not used it in the mingw shell, but rather use the g++ that I installed alongside mingw – SamTheProgrammer Feb 14 '22 at 19:46
  • @akm I tried this on WSL, it works. Do you know of any windows solutions, perhaps with dlls? – SamTheProgrammer Feb 14 '22 at 20:20
  • 1
    So can you run a C++ program from within a cmd window? – n. m. could be an AI Feb 14 '22 at 22:03
  • 1
    See [this](https://stackoverflow.com/questions/18583061/c-dll-loads-in-c-program-not-in-python-ctypes/18650202#18650202) for debugging which file can't be found. The code works with the Microsoft compiler using `__declspec(dllexport` and `.dll` files. Use a DLL and make sure the C++ runtime is also present in the same directory or DLL search path or it is statically linked – Mark Tolonen Feb 15 '22 at 01:34
  • 1
    @Password-Classified Related, [this](https://stackoverflow.com/questions/59330863/cant-import-dll-module-in-python?noredirect=1&lq=1) can help you... – akm Feb 15 '22 at 07:50
  • @n.1.8e9-where's-my-sharem. Yes I can. – SamTheProgrammer Feb 15 '22 at 09:35
  • @MarkTolonen I tried that, but it does not work. – SamTheProgrammer Feb 15 '22 at 09:40
  • 2
    OK try to examine (1) your library and (2) your executable in the dependency walker. Do you see a dependency in one that is not in the other? Also try building with `-static-libstdc++ -static-libgcc` flags. – n. m. could be an AI Feb 15 '22 at 09:41
  • 1
    This is most likely a duplicate of [\[SO\]: Why does adding multiprocessing prevent python from finding my compiled c program? (@CristiFati's answer)](https://stackoverflow.com/a/75035737/4788546) (or [\[SO\]: Can't import dll module in Python (@CristiFati's answer)](https://stackoverflow.com/a/59333711/4788546)). Read the instructions (including referenced *URL*s), add the corresponding paths and you should be fine. – CristiFati Mar 25 '23 at 13:39

2 Answers2

1

Looks like a path issue based on the error. I was able to quickly try out your example, and it worked for me. This error probably has nothing to do with iostream, but you could confirm that by changing the function quickly to use printf.

I do not have experience working on c++ in windows 10, but could you check if you're able to find the library file in python, before accessing using something like the below code

import os    
print(os.path.exists('./lib.so'))
anirudh
  • 4,116
  • 2
  • 20
  • 35
1

I encountered exactly the same problem on Win 10, MinGW & Python 3.7-3.10.

I finally used dependencywalker and found out that the importing relies on the compiler environment. With exaction of dependent dlls I solved this problem. Using static compile mode also helps.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Serena
  • 19
  • 3
  • Thanks for making the modifications; if you happen to remember, can you include the command line option (or other brief instruction) on how to enable static linking on the MinGW environment? – nanofarad Mar 23 '22 at 01:48
  • Can you explain how to use static compile mode? – SamTheProgrammer Aug 16 '23 at 12:21