4

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?

smajli
  • 313
  • 1
  • 6
  • 15
  • 1
    `gcc -shared example.o example_wrap.o -o _example.so`. – CristiFati Apr 25 '18 at 14:24
  • @CrisFati your solution works partially: when I do 'import example' in python interpreter it doesn't give traceback, but doing later for example fract(4) it says: 'NameError: name 'fact' is not defined.' Anyway, when I do start python this way: 'python -i example.py' I don't have to import anything and fact(4) gives proper answer of 24. What is the problem now? – smajli Apr 25 '18 at 14:36
  • 1
    `example.fact(4)` (*DOT* **not** *SPACE*). And the name is `fact` (your comment also mentions `fract`). – CristiFati Apr 25 '18 at 14:38
  • Great! You can make it an answer. With second comment as well. It is an important bit to this subject. – smajli Apr 25 '18 at 14:40

2 Answers2

6

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:

CristiFati
  • 38,250
  • 9
  • 50
  • 87
0

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

The naming is wrong and causing the error.

expreun9
  • 1
  • 2