c program SWIG to python gives 'ImportError: dynamic module does not define init function'

Question:

I am trying to use .c program in python script with SWIG. To start with, I installed SWIG and trying simple example from tutorial swig webpage.

I am using Raspberry Pi with Raspbian GNU/Linux 9.4 (stretch)

This is what I do:
1. swig -python example.i – great, this created two new files: ‘example.py’ and ‘example_wrap.c’
2. gcc -fpic -I/usr/include/python2.7 -c example_wrap.c – this creates ‘example_wrap.o’ file
3. compile example.c in Geany; this gives ‘example.o’ file
4. gcc -shared example.o example_wrap.o -o example.so – now a new file ‘example.so’ is created.
Time to try it:

python

I am using Python 2.7.13 here

>>>import example

And this gives traceback:

File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initexample)

How to sort this problem out?

Asked By: smajli

||

Answers:

Like CristiFati said “gcc -shared example.o example_wrap.o -o _example.so”

The naming is wrong and causing the error.

Answered By: expreun9

This is what happens for a dynamic Python module (at least, in current swig version):

  • The module name (let’s stick with example, like in the tutorial) is specified in the .i file: %module example

  • At build time, 2 files are generated:

    • _${MODULE_NAME}.so: a dynamic module or shared object having the name the module name preceded by an UnderScore, in our example _example.so, which contain the actual C compiled code

    • ${MODULE_NAME}.py: which is a wrapper over the previous one; example.py – this is the module "entry point"

A Python dynamic module must export an init* function (PyInit_* in Python 3) as explained on [Python 2.Docs]: The Module’s Method Table and Initialization Function, and more: what comes after the init part, must match module (.so) name (in our case it’s init_example).

By naming the dynamic module example.so, when Python tried to load it, it searched for initexample which (obviously) didn’t exist, raising ImportError.

Changing the module name to _example.so (gcc -shared example.o example_wrap.o -o _example.so), as the URL also instructs, no longer raises an exception.

Then, the functions are available like this:

>>> import example  # This imports example.py which automatically imports _example.so
>>> example.fact(4), example.my_mod(7, 2), example.get_time()

Might also want to check:

Answered By: CristiFati
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.