SWIG Tutorial
So you want to get going in a hurry? To illustrate the use of SWIG, suppose you have some C functions you want added to Tcl, Perl, Python and Java. Specifically, let's say you have them in a file 'example.c'
/* File : example.c */
#include <time.h>
double My_variable = 3.0;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
int my_mod(int x, int y) {
return (x%y);
}
char *get_time()
{
time_t ltime;
time(<ime);
return ctime(<ime);
}
/* example.i */
%module example
%{
/* Put header files here (optional) */
%}
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
unix % swig -tcl example.i
unix % gcc -fpic -c 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 example
% puts $My_variable
3.0
% fact 5
120
% my_mod 7 3
1
% get_time
Sun Feb 11 23:01:07 1996
%
The swig command produces a file
example_wrap.c that should be compiled and linked with
the rest of the program. In this case, we have built a dynamically
loadable extension that can be loaded into the Tcl interpreter using
the 'load' command.
unix % swig -python example.i
unix % gcc -c example.c example_wrap.c \
-I/usr/local/include/python2.1
unix % ld -shared example.o example_wrap.o -o _example.so
We can now use the Python module as follows :
>>> import example >>> example.fact(5) 120 >>> example.my_mod(7,3) 1 >>> example.get_time() 'Sun Feb 11 23:01:07 1996' >>>
unix % swig -perl5 example.i
unix % gcc -c example.c example_wrap.c \
-I/usr/lib/perl/solaris/5.003/CORE
unix % ld -G example.o example_wrap.o -o example.so
unix % perl
use example;
print $example::My_variable,"\n";
print example::fact(5),"\n";
print example::get_time(),"\n";
<ctrl-d>
3.0
120
Sun Feb 11 23:01:07 1996
unix %
$ swig -java example.i
$ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
$ gcc -shared example.o example_wrap.o -Wl,--add-stdcall-alias -o example.dll
$ cat main.java
public class main {
public static void main(String argv[]) {
System.loadLibrary("example");
System.out.println(example.getMy_variable());
System.out.println(example.fact(5));
System.out.println(example.get_time());
}
}
$ javac main.java
$ java main
3.0
120
Mon Mar 4 18:20:31 2002
$
%module example
%{
/* Includes the header in the wrapper code */
#include "header.h"
%}
/* Parse the header file to generate wrappers */
%include "header.h"
Alternatively, some people might just include SWIG directives in a header
file with conditional compilation. For example:
#ifdef SWIG
%module example
%{
#include "header.h"
%}
#endif
extern int fact(int n);
...
To illustrate, suppose you wanted to wrap the following C++ data structure:
// pair.h. A pair like the STL
namespace std {
template<class T1, class T2> struct pair {
T1 first;
T2 second;
pair() : first(T1()), second(T2()) { };
pair(const T1 &f, const T2 &s) : first(f), second(s) { }
};
}
To wrap with SWIG, you might specify the following interface:
// pair.i - SWIG interface
%module pair
%{
#include "pair.h"
%}
// Ignore the default constructor
%ignore std::pair::pair();
// Parse the original header file
%include "pair.h"
// Instantiate some templates
%template(pairii) std::pair<int,int>;
%template(pairdi) std::pair<double,int>;
Now, compiling (Python):
$ swig -proxy -python -c++ pair.i $ c++ -c pair_wrap.c -I/usr/local/include/python2.1 $ c++ -shared pair_wrap.c -o paircmodule.so $ python Python 2.1 (#3, Aug 20 2001, 15:41:42) [GCC 2.95.2 19991024 (release)] on sunos5 Type "copyright", "credits" or "license" for more information. >>> import pair >>> a = pair.pairii(3,4) >>> a.first 3 >>> a.second 4 >>> a.second = 16 >>> a.second 16 >>> b = pair.pairdd(3.5,8) >>> b.first 3.5 >>> b.second 8