"Linux Gazette...making Linux just a little more fun!"

Using SWIG to interface scripting languages with C/C++

Introduction

Scripting languages like Perl, Python and Tcl are receiving a lot of attention nowadays - mainly because
these languages facilitate Rapid Application Development and Prototyping. It has been shown
time and again that using a language like Python cuts down development time drastically - with the added
advantage that you get highly robust and flexible code. But there are situations in which a
pure scripting approach does not work, typical examples being scientific applications which require high
speed math and graphics routines or applications which need to control and coordinate hardware devices
on a real time basis. What we need is a mixed-language paradigm in which traditional systems languages
like C/C++ do the 'dirty' low-level work while the Scripting language acts as the overall supervisor. This
article focuses on using an excellent program called the Simplified Wrapper and Interface Generator (SWIG)
to integrate code written in C/C++ with the popular scripting language Python. The code fragments in this article have
been tested on a Red Hat Linux (5.2) machine running Python ver 1.5.1.

Getting and Installing SWIG

SWIG is being developed by Dave Beazley and can be downloaded from www.swig.org.
Installation is straightforward, just run ./configure and then make. Currently, SWIG supports Perl, Python,
Tcl and FSF Guile.

A simple example

Let us say we have a C function called add(a, b) which returns the sum of two numbers passed to it as
arguments. We will see how the add function can be made Python-callable.
We will create a file called arith.c which contains the following code:

int add(int a, int b)
{
return a+b;
}

Let us now execute the following command:

swig -python -module arith arith.c

We see that SWIG has created two new files, arith_wrap.c and arith_wrap.doc. We should now compile both arith.c and
arith_wrap.c to produce object files, the command being:

gcc -I/usr/include/python1.5 -c arith.c arith_wrap.c

The object files arith.o and arith_wrap.o should now be combined to produced a shared object called arith.so:

ld -shared -o arith.so arith.o arith_wrap.o

If everything goes well, we will have a file called arith.so in our current directory. Here is a sample
interaction using the arith module:

import arith
>>>arith.add(10, 20)
30
>>>arith.add(10, -10)
0
>>>

Does using C improve speed?

We will find out! Let us add one more function to our arith.c file and then rebuild arith.so:

The proper way of using SWIG

SWIG generates wrappers not by looking at how your C code works internally, but by seeing the interface
specification. Here is how we should have proceeded.
First, create an interface file, arith.i. The file should contain the following
lines:

%module arith
extern int add(int a, int b);
extern int fact(int n);

Now generate the wrappers by running swig -python arith.i, compile into object files and use ld to create
arith.so.

A low-level interfacing example

The PC's parallel port can be used to perform some very amusing hardware interfacing
experiments. On Linux, we have functions like inb(), outb() etc which can be used to access I/O ports.
Here is a C program which writes to the printer port:

#include <asm/io.h>
int main()
{
iopl(3);
outb(1, 0x378);
}

The program should be compiled as cc -O2 io.c and it should be executed with superuser privilege. The iopl
call is required to make the IO ports accessible to user programs. How do we write a Python version of this
program? Simple. Use SWIG to make Python callable versions of outb(), inb() and iopl(). Here is an io.c module
tailored for SWIG:

It is even possible to request SWIG to generate Python shadow classes automatically!

Conclusion

SWIG is a useful tool, easy to learn and easy to apply. Though we have only examined SWIG in the
context of Python scripting, usage with other languages like Perl and Tcl is very similar. The
SWIG Home Page is the definitive source for more information.