Search code examples
pythoncswigpython-c-api

Issue with SWIG for creating Python bindings for C library


I want to use SWIG to create Python bindings for C library, but I have some troubles with it. I used the following .c and .i files from tutorial. example.c

/* Compute factorial of n */
int fact(int n) {
  if (n <= 1)
    return 1;
  else
    return n*fact(n-1);
}

/* Compute n mod m */
int my_mod(int n, int m) {
  return(n % m);
}

double My_variable;

example.i

%module example
%{
extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);
%}

extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);

Commands that I used:

$ swig -python -py3 example.i
$ gcc -c -fpic example.c example_wrap.c -I/usr/include/python3.6
$ gcc -shared example.o example_wrap.o -o example.so

And when I try to import it in python3 I am getting this

>>> import example
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_example)

Any help appreciated


Solution

  • SWIG generates a module with underscore prepended by default, so you'll get a module called _example which needs to be in _example.so.

    This is explained in the SWIG documentation 34.2.3 Hand compiling a dynamic module:

    While the preferred approach to building an extension module is to use the distutils, some people like to integrate building extensions with a larger build system, and thus may wish to compile their modules without the distutils. To do this, you need to compile your program using commands like this (shown for Linux):

    $ swig -python example.i
    $ gcc -O2 -fPIC -c example.c
    $ gcc -O2 -fPIC -c example_wrap.c -I/usr/local/include/python2.5
    $ gcc -shared example.o example_wrap.o -o _example.so
    

    The exact commands for doing this vary from platform to platform. However, SWIG tries to guess the right options when it is installed. Therefore, you may want to start with one of the examples in the SWIG/Examples/python directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for additional information.

    When linking the module, the name of the output file has to match the name of the module prefixed by an underscore. If the name of your module is example, then the name of the corresponding object file should be _example.so or _examplemodule.so. The name of the module is specified using the %module directive or the -module command line option.

    Compatibility Note: In SWIG-1.3.13 and earlier releases, module names did not include the leading underscore. This is because modules were normally created as C-only extensions without the extra Python support file (instead, creating Python code was supported as an optional feature). This has been changed in SWIG-1.3.14 and is consistent with other Python extension modules. For example, the socket module actually consists of two files; socket.py and _socket.so. Many other built-in Python modules follow a similar convention.