Introduction

# 1 Introduction

- What is SWIG?
- Why use SWIG?
- A SWIG example
  - SWIG interface file
  - The swig command
  - Building a Perl5 module
  - Building a Python module
  - Shortcuts
  - Building libraries and modules
- Supported C/C++ language features
- Non-intrusive interface building
- Hands off code generation

## 1.1 What is SWIG?

SWIG is a software development tool that simplifies the task of interfacing different languages to C and C++ programs. In a nutshell, SWIG is a compiler that takes C declarations and creates the wrappers needed to access those declarations from other languages including including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally requires no modifications to existing code and can often be used to build a usable interface in only a few minutes. Possible applications of SWIG include:

- Building interpreted interfaces to existing C programs.
- Rapid prototyping and application development.
- Interactive debugging.
- Reengineering or refactoring of legacy software into a scripting language components.
- Making a graphical user interface (using Tk for example).
- Testing of C libraries and programs (using scripts).
- Building high performance C modules for scripting languages.
- Making C programming more enjoyable (or tolerable depending on your point of view)
- Impressing your friends.
- Obtaining vast sums of research funding (although obviously not applicable to the author).

SWIG was originally designed to make it extremely easy for scientists and engineers to build extensible scientific software without having to get a degree in software engineering. Because of this, the use of SWIG tends to be somewhat informal and ad-hoc (e.g., SWIG does not require users to provide formal interface specifications as you would find in a dedicated IDL compiler). Although this style of development isn't appropriate for every project, it is particularly well suited to software development in the small; especially the research and development work that is commonly found in scientific and engineering projects.

## 1.2 Why use SWIG?

Although C is great for high-performance number crunching and systems programming, trying to make an interactive and highly flexible C program is a pain. Even though it is possible to build a user interface using command line options, a home grown command interpreter, or a graphical user interface, this often results in a program that is hard to extend, hard to modify, hard to port between platforms, and hard to use. Furthermore, this sort of activity wastes a lot of development time because it usually diverts everyone's attention away from the real problem that they're trying to solve.

Many of the problems with C are due to the way in which many programs are organized. For example, a lot of programs are structured as follows:

- A collection of functions and variables that do something useful.
- A `main()` program that starts everything.
- A horrible collection of hacks that form some kind of user interface (but which no-one really wants to touch).

In this case, the `main()` program may read command line options or simple commands from `stdin`. However, modifying or extending the program to do something new requires changing the C code, recompiling, and testing. If you make a mistake, you need to repeat this cycle until things work. Of course, as more and more features are added, the program usually turns into a horrible mess that is even more difficult to modify than before (although this undoubtedly increases the job security of the programmer).

A common mistake is to assume that all of the problems with C can somehow be fixed by using a better C---perhaps an undebuggable language with unreadable syntax, complicated semantics, and nearly infinite compilation time. This is an unfortunate.

Perhaps a better approach is to place your application under the control of a very high-level language such as a common scripting language interpreter. High level languages excel at turning hard problems into easy tasks. They also provide a nice framework for managing software components and gluing different systems together. Not only that, they make it easy for users to configure the software to their liking and to program it to perform new tasks without ever having to touch a C/C++ compiler.

SWIG simplifies the task of incorporating C++ code into a high-level programming environment. Specifically, rather than creating a huge monolithic package, SWIG allows you to restructure your application as a collection of functions and variables that can be accessed from the convenience of a high-level language. With this model, all of the functionality of your C program is retained. The only difference is that the high-level program logic and control is now driven by the high-level language instead of a low level `main()` function.

SWIG tries to make the integration between scripting languages and C as painless as possible. This allows you to focus on the underlying C program and using the high-level scripting language interface, but not the tedious and complex chore of making the two languages talk to each other.

## 1.3 A SWIG example

The best way to illustrate SWIG is with a simple example. Consider the following C code:

>     /* File : example.c */

>     double  My_variable  = 3.0;

>     /* 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);
>     }

Suppose that you wanted to access these functions and the global variable `My_variable` from Tcl. You start by making a SWIG interface file as shown below (by convention, these files carry a .i suffix) :

### 1.3.1 SWIG interface file

>     /* File : example.i */
>     %module example
>     %{
>     /* Put headers and other declarations here */
>     %}

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

The interface file contains ANSI C function prototypes and variable declarations. The `%module` directive defines the name of the module that will be created by SWIG. The `%{,%}` block provides a location for inserting additional code such as C header files or additional C declarations.

### 1.3.2 The swig command

SWIG is invoked using the `swig` command. We can use this to build a Tcl module (under Linux) as follows :

>     unix > swig -tcl example.i
>     unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include
>     unix > gcc -shared example.o example_wrap.o -o example.so
>     unix > tclsh
>     % load ./example.so
>     % fact 4
>     24
>     % my_mod 23 7
>     2
>     % expr $My_variable + 4.5
>     7.5
>     %

The `swig` command produced a new file called `example_wrap.c` that should be compiled along with the `example.c` file. Most operating systems and scripting languages now support dynamic loading of modules. In our example, our Tcl module has been compiled into a shared library that can be loaded into Tcl. When loaded, Tcl can now access the functions and variables declared in the SWIG interface. A look at the file `example_wrap.c` reveals a hideous mess. However, you almost never need to worry about it.

### 1.3.3 Building a Perl5 module

Now, let's turn these functions into a Perl5 module. Without making any changes type the following (shown for Solaris):

>     unix > swig -perl5 example.i
>     unix > gcc -c example.c example_wrap.c \
>     	-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
>     unix> ld -G example.o example_wrap.o -o example.so		# This is for Solaris
>     unix > perl5.003
>     use example;
>     print example::fact(4), "\n";
>     print example::my_mod(23,7), "\n";
>     print $example::My_variable + 4.5, "\n";
>     <ctrl-d>
>     24
>     2
>     7.5
>     unix >

### 1.3.4 Building a Python module

Finally, let's build a module for Python (shown for Irix).

>     unix > swig -python example.i
>     unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0
>     unix > gcc -shared example.o example_wrap.o -o _example.so
>     unix > python
>     Python 2.0 (#6, Feb 21 2001, 13:29:45)
>     [GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
>     Type "copyright", "credits" or "license" for more information.
>     >>> import example
>     >>> example.fact(4)
>     24
>     >>> example.my_mod(23,7)
>     2
>     >>> example.cvar.My_variable + 4.5
>     7.5

### 1.3.5 Shortcuts

To the truly lazy programmer, one may wonder why we needed the extra interface file at all. As it turns out, you can often do without it. For example, you could also build a Perl5 module by just running SWIG on the C header file and specifying a module name as follows

>     unix> swig -perl5 -module example example.h
>     unix > gcc -c example.c example_wrap.c \
>     	-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
>     unix> ld -G example.o example_wrap.o -o example.so
>     unix > perl5.003
>     use example;
>     print example::fact(4), "\n";
>     print example::my_mod(23,7), "\n";
>     print $example::My_variable + 4.5, "\n";
>     <ctrl-d>
>     24
>     2
>     7.5

### 1.3.6 Building libraries and modules

In addition to generating wrapper code, SWIG provides extensive support for handling multiple files and building interface libraries. For example, our `example.i` file, could be used in another interface as follows :

>     %module foo
>     %include example.i             // Get definitions from example.i

>     ... Now more declarations ...

In a large system, an interface might be built from a variety of pieces like this :

>     %module package

>     %include network.i
>     %include file.i
>     %include graphics.i
>     %include objects.i
>     %include simulation.i

SWIG comes with a library of existing functions known as the SWIG library. The library contains a mix of language independent and language dependent functionality. For example, the file ``array.i`' provides access to C arrays while the file ``wish.i`' includes specialized code for rebuilding the Tcl wish interpreter. Using the library, you can use existing modules to build up your own personalized environment for building interfaces. If changes are made to any of the components, they will appear automatically the next time SWIG is run.

## 1.4 Supported C/C++ language features

A primary goal of the SWIG project is to make the language binding process extremely easy. Although a few simple examples have been shown, SWIG is quite capable in supporting most of C++. Some of the major features include:

- Full C99 preprocessing.
- All ANSI C and C++ datatypes.
- Functions, variables, and constants.
- Classes.
- Single and multiple inheritance.
- Overloaded functions and methods.
- Overloaded operators.
- C++ templates (including member templates, specialization, and partial specialization).
- Namespaces.
- Variable length arguments.
- C++ smart pointers.

Currently, the only C++ feature not supported is nested classes--a limitation that will be removed in a future release.

It is important to stress that SWIG is not a simplistic C++ lexing tool like several apparently similar wrapper generation tools. SWIG not only parses C++, it implements the full C++ type system and it is able to understand C++ semantics. SWIG generates its wrappers with full knowledge of this information. As a result, you will find SWIG to be just as capable of dealing with nasty corner cases as it is in wrapping simple C++ code. In fact, SWIG is able handle C++ code that stresses the very limits of many C++ compilers.

## 1.5 Non-intrusive interface building

When used as intended, SWIG requires minimal modification to existing C code. This makes SWIG extremely easy to use with existing packages and promotes software reuse and modularity. By making the C code independent of the high level interface, you can change the interface and reuse the code in other applications. It is also possible to support different types of interfaces depending on the application.

## 1.6 Hands off code generation

SWIG is designed to produce working code that needs no hand-modification (in fact, if you look at the output, you probably won't want to modify it). Ideally, SWIG should be invoked automatically inside a Makefile just as one would call the C compiler. You should think of your scripting language interface being defined entirely by the input to SWIG, not the resulting output file. While this approach may limit flexibility for hard-core hackers, it allows others to forget about the low-level implementation details.