c++python-3.xlinuxshared-librariesctypes

importing a .py file which imports an .so file via ctypes - error "dynamic module does not define module export function"


I work under Linux.

  1. I wrote a file a.cpp (where there is a function f for which I make an extern "c" {} declaration at the top of the file).
  2. I compiled g++ -shared -fPIC -o a.so a.cpp.
  3. I wrote a.py where I have ctypes.cdll.LoadLibrary('./a.so'). If I actually run this file then everything is fine and I can call the function f.
  4. I wrote b.py which has import a. Here I get an error at that import line: dynamic module does not define module export function (PyInit_a).

I guess I need to somehow modify the import with some __init__ or something, but maybe something else. Does somebody know what to do?

Thanks!


Solution

  • Listing [Python.Docs]: ctypes - A foreign function library for Python.

    There are a couple of ways of overcoming this. The most straightforward is to specify the full path of the .so file. So, if a.py and a.so are inside the same directory (if they are in different directories, computing the relative path would also be trivial), here's what you could do:

    dll = ctypes.CDLL(os.path.join(os.path.dirname(os.path.abspath(__file__)), "a.so"))
    # ...
    

    This should work on all scenarios. There are some other workarounds (like the one you found) that might work on some of them, but they are influenced by factors like:

    Here I only discussed the trivial case where a.so has no custom dependencies (residing in other places).

    Also note that by naming your library a.so (and also having a script a.py), you are confusing the interpreter (to be more precise: import a), which also searches a.so as if it was an extension module ([Python.Docs]: Extending Python with C or C++), that's why you get the (last) ImportError. I'd suggest renaming a.so to something else like:

    Of course, if moving towards production, you should give your modules meaningful names.

    Might also be helpful: