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?
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: