git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4008 626c5289-ae23-0410-ae9c-e8d60b6d4f22
288 lines
7.4 KiB
Text
Executable file
288 lines
7.4 KiB
Text
Executable file
SWIG Tutorial
|
|
|
|
<p>
|
|
<img src="images/tutorial.png">
|
|
|
|
<p>
|
|
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'
|
|
|
|
<ul><tt><pre>
|
|
/* 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(&ltime);
|
|
return ctime(&ltime);
|
|
}
|
|
|
|
</pre></tt></ul>
|
|
|
|
<h3>Interface file </h3>
|
|
|
|
Now, in order to add these files to your favorite language, you need to write an
|
|
"interface file" which is the input to SWIG. An interface file for these
|
|
C functions might look like this :
|
|
|
|
<ul><tt><pre>
|
|
/* 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();
|
|
</pre></tt></ul>
|
|
|
|
<h3> Building a Tcl module </h3>
|
|
|
|
At the UNIX prompt, type the following (shown for Linux, see the <a href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl?SwigFaq/SharedLibraries">SWIG Wiki Shared Libraries</a> page for help with other operating systems):
|
|
|
|
<blockquote>
|
|
<pre><tt>
|
|
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
|
|
|
|
%
|
|
</tt></pre></blockquote>
|
|
|
|
The <tt> swig </tt> command produces a file <a href = "tutorial/example_wrap.html">
|
|
<tt> example_wrap.c </tt> </a> 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.
|
|
|
|
<h3> Building a Python module </h3>
|
|
|
|
Turning C code into a Python module is also easy. Simply do the following (shown for Irix, see the <a href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl?SwigFaq/SharedLibraries">SWIG Wiki Shared Libraries</a> page for help with other operating systems):
|
|
|
|
<blockquote> <tt> <pre>
|
|
|
|
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
|
|
</pre> </tt> </blockquote>
|
|
|
|
We can now use the Python module as follows :
|
|
<blockquote> <tt> <pre>
|
|
>>> import example
|
|
>>> example.fact(5)
|
|
120
|
|
>>> example.my_mod(7,3)
|
|
1
|
|
>>> example.get_time()
|
|
'Sun Feb 11 23:01:07 1996'
|
|
>>>
|
|
</pre>
|
|
</tt> </blockquote>
|
|
|
|
<h3> Building a Perl module </h3>
|
|
You can also build a Perl5 module as follows (shown for Solaris, see the <a href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl?SwigFaq/SharedLibraries">SWIG Wiki Shared Libraries</a> page for help with other operating systems):
|
|
|
|
<blockquote><tt><pre>
|
|
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 %
|
|
</pre></tt></blockquote>
|
|
|
|
<h3> Building a Java module </h3>
|
|
SWIG will also generate JNI code for accessing C/C++ code from Java. Here is an example building a Java module (shown for Cygwin, see the <a href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl?SwigFaq/SharedLibraries">SWIG Wiki Shared Libraries</a> page for help with other operating systems):
|
|
|
|
<blockquote><tt><pre>
|
|
$ 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
|
|
$
|
|
</pre></tt></blockquote>
|
|
|
|
<h3> SWIG for the truly lazy </h3>
|
|
|
|
As it turns out, it is not always necessary to write a special interface
|
|
file. If you have a header file, you can often just include it directly in the
|
|
SWIG interface. For example:
|
|
|
|
<blockquote>
|
|
<tt> <pre>
|
|
%module example
|
|
%{
|
|
/* Includes the header in the wrapper code */
|
|
#include "header.h"
|
|
%}
|
|
|
|
/* Parse the header file to generate wrappers */
|
|
%include "header.h"
|
|
</pre></tt>
|
|
</blockquote>
|
|
|
|
Alternatively, some people might just include SWIG directives in a header
|
|
file with conditional compilation. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
#ifdef SWIG
|
|
%module example
|
|
%{
|
|
#include "header.h"
|
|
%}
|
|
#endif
|
|
|
|
extern int fact(int n);
|
|
...
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h3> Running SWIG under Microsoft Windows </h3>
|
|
|
|
SWIG also works perfectly well under all known 32 bit versions of
|
|
Windows including 95/98/NT/2000/XP. SWIG is typically invoked from
|
|
the command prompt and can be used with NMAKE. Modules are typically
|
|
compiled in the form of a DLL that can be dynamically loaded into Tcl,
|
|
Python, or whatever language you are using. With a little work, SWIG
|
|
can also be used as a custom build option within MS Developer Studio.
|
|
|
|
<h3>That's it (well, more or less)</h3>
|
|
|
|
That's about everything you need to know to get started. Here's the short checklist :
|
|
|
|
<ul>
|
|
<li> Make sure you specify a module name.
|
|
<li> Use ANSI C/C++ syntax
|
|
<li> Figure out how to compile a shared library module / dynamic link library (may require reading a few man
|
|
pages for your compiler).
|
|
<li> Relax.
|
|
</ul>
|
|
|
|
<h3>Surely there's more to it...</h3>
|
|
|
|
The above example is intentionally simple, but the general idea
|
|
extends to more complicated C/C++ programming tasks. In fact, it is
|
|
important to know that SWIG is a fairly complete C++ compiler with
|
|
support for nearly every language feature. This includes
|
|
preprocessing, pointers, classes, inheritance, and even C++ templates.
|
|
SWIG can also be used to package structures and classes into proxy
|
|
classes in the target language---exposing the underlying functionality in a very
|
|
natural manner.
|
|
|
|
<p>
|
|
To illustrate, suppose you wanted to wrap the following C++ data structure:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
// 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) { }
|
|
};
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
To wrap with SWIG, you might specify the following interface:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
// 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>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Now, compiling (Python):
|
|
|
|
<blockquote>
|
|
<pre>
|
|
$ 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
|
|
</pre>
|
|
</blockquote>
|
|
|