SWIG (Simplified Wrapper and Interface Generator) is an interface compiler that connects programs written in C and C++ with scripting languages such as Python, Tcl, Perl, ... The goal of this document is to explain through a simple example how to install and use SWIG to connect a C++ library with a Python script.
We will work with the C++ library AddNumbers: AddNumbers.tar.bz2. Read the Create and use static and shared C++ libraries tutorial that explains how to create, compile and link a shared library.
Click on the following link to download the SWIG_AddNumbersClient example: SWIG_AddNumbersClient.tar.bz2.
operating system | version |
---|---|
Linux RH Enterprise 4 | kernel 2.6.9-11 |
program | version |
g++ | 3.4.3 |
python | 2.3.4 |
swig | 1.3.31 |
Download the latest version of the SWIG program: swig-1.3.31.tar.gz. The following list of commands creates a directory swig under the local directory that contains programs, and creates a subdirectory 1.3.31.
[~/softs/swig] > tar -zxvf swig-1.3.31.tar.gz ... [~/softs/swig] > rm -f swig-1.3.31.tar.gz [~/softs/swig] > mv swig-1.3.31 1.3.31 [~/softs/swig] > ln -s 1.3.31 default
Go to the directory swig/1.3.31 and executes the following command that prepare the GNU Make program to install a local version of SWIG.
[~/softs/swig/1.3.31] > ./configure --prefix=${HOME}/softs/swig/1.3.31
If no problem is reported by the previous command compile and then install SWIG.
[~/softs/swig/1.3.31] > make ... [~/softs/swig/1.3.31] > make install
Finally create a link in the local bin directory.
[~/bin] > ln -s ../softs/swig/default/bin/swig
Insure that the directory ${HOME}/bin is in your PATH environment variable, at the first position (because you want probably to use the last installed version of swig instead of the possible default installed). If not then execute the following command.
[~] > PATH=${HOME}/bin:${PATH}
First let us look furtively the C++ class interface we want to work with.
~/workspace/c++/AddNumbers/inc/AddNumbers.h
#ifndef _ADDNUMBERS_H #define _ADDNUMBERS_H class AddNumbers { private: int _a; int _b; public: AddNumbers (); ~AddNumbers (); void setA (int a); void setB (int b); int getA () const; int getB () const; int getSum () const; }; // AddNumbers #endif // _ADDNUMBERS_H
The following code is the SWIG interface file that correspond with the previous C++ interface. It is not mandatory to declare in this interface all members and methods from the C++ one: only those we want to use with Python scripts. So we did not declared private members.
~/workspace/python/SWIG_AddNumbersClient/int/AddNumbers.i
%module AddNumbers %{ #include "AddNumbers.h" %} class AddNumbers { public: AddNumbers (); ~AddNumbers (); void setA (int a); void setB (int b); int getA () const; int getB () const; int getSum () const; };
The command swig compiles the interface.
[~/workspace/python/SWIG_AddNumbersClient] > swig -c++ -python -o src/AddNumbers_wrap.cpp -outdir lib int/AddNumbers.i
Two files are generated: a Python module lib/AddNumbers.py and a C++ wrapper src/AddNumbers_wrap.cpp. Now we will create the shared wrapper library. First step is to compile both C++ library and wrapper source files.
[~/workspace/python/SWIG_AddNumbersClient] > g++ -I ../../c++/AddNumbers/inc \ > -fpic -c ../../c++/AddNumbers/src/AddNumbers.cpp -o obj/AddNumbers.o [~/workspace/python/SWIG_AddNumbersClient] > g++ -I /usr/include/python2.3 -I ../../c++/AddNumbers/inc \ > -fpic -c src/AddNumbers_wrap.cpp -o obj/AddNumbers_wrap.o
Second step consists of linking object files. Note that names of the module (AddNumbers.py) and the shared library (_AddNumbers.so) should match.
[~/workspace/python/SWIG_AddNumbersClient] > g++ -shared -o lib/_AddNumbers.so obj/AddNumbers.o obj/AddNumbers_wrap.o
This solution needs to compile source files of the original shared library. A better solution consists of work with both original shared library and a wrapper library built only with the wrapper object file. We repeat the first two previous steps: compilation of the SWIG interface and compilation of the wrapper generated source file.
[~/workspace/python/SWIG_AddNumbersClient] > swig -c++ -python -o src/AddNumbers_wrap.cpp -outdir lib int/AddNumbers.i [~/workspace/python/SWIG_AddNumbersClient] > g++ -I /usr/include/python2.3 -I ../../c++/AddNumbers/inc \ > -fpic -c src/AddNumbers_wrap.cpp -o obj/AddNumbers_wrap.o
Then we link with the original shared library.
[~/workspace/python/SWIG_AddNumbersClient] > g++ -shared -L ../../c++/AddNumbers/lib -lAddNumbers \ > -o lib/_AddNumbers.so obj/AddNumbers_wrap.o
Don't forget to add in the LD_LIBRARY_PATH environment variable the path of the libAddNumbers.so library.
[~] > export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${HOME}/workspace/c++/AddNumbers/lib
As an example see the Makefile file in SWIG_AddNumbersClient.tar.bz2.
Let's write the following Python script.
~/workspace/python/SWIG_AddNumbersClient/src/AddNumbersClient.py
#!/usr/bin/python import sys sys.path.append('lib') from AddNumbers import * ab = AddNumbers() ab.setA(4) ab.setB(3) print '%d + %d = %d' % (ab.getA(), ab.getB(), ab.getSum())
Then launch it.
[~/workspace/python/SWIG_AddNumbersClient] > src/AddNumbersClient.py 4 + 3 = 7
Some notes about SWIG and C++ are drag from the SWIG documentations.
SWIG only provides support for a subset of C++ features. The SWIG parser has the following limitations.
SWIG supports the following C++ features.
But the following C++ features are not supported.
swig [option] ... <filename>
SWIG is invoked using the swig command.
option | description |
---|---|
-python | Generate Python wrappers. |
-c++ | Enable C++ handling. |
-I<dir> | Set SWIG include directory to dir. |
-module <name> | Set module name to name. |
-o <outfile> | Set name of the output file to outfile. |
-outdir <dir> | Set language specific files output directory to dir. |
-Wall | Enable all warning messages. |
link | comment |
---|---|
GNU GCC manual | g++ manual |
Python documentation | python manual |
SWIG documentation | swig manual |
document | comment |
---|---|
SWIG Users Manual | Version 1.1, June 1997 (318 pages) Be careful about this documentation, some things are wrong or obsolete. Refer to the SWIG 1.3 Documentation. |
SWIG 1.3 Documentation | November 20th 2006 (602 pages) |
Interfacing C/C++ and Python with SWIG | 7th International Python Conference (115 pages) |