mirror of https://github.com/swig/swig
3040 lines
87 KiB
HTML
3040 lines
87 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>SWIG Basics</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="SWIG"></a>5 SWIG Basics</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#SWIG_nn2">Running SWIG</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn3">Input format</a>
|
|
<li><a href="#output">SWIG Output</a>
|
|
<li><a href="#SWIG_nn5">Comments</a>
|
|
<li><a href="#SWIG_nn6">C Preprocessor</a>
|
|
<li><a href="#SWIG_nn7">SWIG Directives</a>
|
|
<li><a href="#SWIG_nn8">Parser Limitations</a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn9">Wrapping Simple C Declarations</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn10">Basic Type Handling</a>
|
|
<li><a href="#SWIG_nn11">Global Variables</a>
|
|
<li><a href="#SWIG_nn12">Constants</a>
|
|
<li><a href="#SWIG_nn13">A brief word about <tt>const</tt></a>
|
|
<li><a href="#SWIG_nn14">A cautionary tale of <tt>char *</tt></a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn15">Pointers and complex objects</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn16">Simple pointers</a>
|
|
<li><a href="#SWIG_nn17">Run time pointer type checking</a>
|
|
<li><a href="#SWIG_nn18">Derived types, structs, and classes</a>
|
|
<li><a href="#SWIG_nn19">Undefined datatypes</a>
|
|
<li><a href="#SWIG_nn20">Typedef</a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn21">Other Practicalities</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn22">Passing structures by value</a>
|
|
<li><a href="#SWIG_nn23">Return by value</a>
|
|
<li><a href="#SWIG_nn24">Linking to structure variables</a>
|
|
<li><a href="#SWIG_nn25">Linking to <tt>char *</tt></a>
|
|
<li><a href="#SWIG_nn26">Arrays</a>
|
|
<li><a href="#SWIG_readonly_variables">Creating read-only variables</a>
|
|
<li><a href="#SWIG_rename_ignore">Renaming and ignoring declarations</a>
|
|
<li><a href="#SWIG_default_args">Default/optional arguments</a>
|
|
<li><a href="#SWIG_nn30">Pointers to functions and callbacks</a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn31">Structures and unions</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn32">Typedef and structures</a>
|
|
<li><a href="#SWIG_nn33">Character strings and structures</a>
|
|
<li><a href="#SWIG_nn34">Array members</a>
|
|
<li><a href="#SWIG_structure_data_members">Structure data members</a>
|
|
<li><a href="#SWIG_nn36">C constructors and destructors </a>
|
|
<li><a href="#SWIG_adding_member_functions">Adding member functions to C structures</a>
|
|
<li><a href="#SWIG_nested_structs">Nested structures</a>
|
|
<li><a href="#SWIG_nn39">Other things to note about structure wrapping</a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn40">Code Insertion</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn41">The output of SWIG</a>
|
|
<li><a href="#SWIG_nn42">Code insertion blocks</a>
|
|
<li><a href="#SWIG_nn43">Inlined code blocks</a>
|
|
<li><a href="#SWIG_nn44">Initialization blocks</a>
|
|
</ul>
|
|
<li><a href="#SWIG_nn45">An Interface Building Strategy</a>
|
|
<ul>
|
|
<li><a href="#SWIG_nn46">Preparing a C program for SWIG</a>
|
|
<li><a href="#SWIG_nn47">The SWIG interface file</a>
|
|
<li><a href="#SWIG_nn48">Why use separate interface files?</a>
|
|
<li><a href="#SWIG_nn49">Getting the right header files</a>
|
|
<li><a href="#SWIG_nn50">What to do with main()</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
This chapter describes the basic operation of SWIG, the structure of its
|
|
input files, and how it handles standard ANSI C declarations. C++ support is
|
|
described in the next chapter. However, C++ programmers should still read this
|
|
chapter to understand the basics.
|
|
Specific details about each target language are described in later
|
|
chapters.
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn2"></a>5.1 Running SWIG</H2>
|
|
|
|
|
|
<p>
|
|
To run SWIG, use the <tt>swig</tt> command with options options and a filename like this:
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
swig [ <em>options</em> ] filename
|
|
</pre></div>
|
|
|
|
<p>
|
|
where <tt>filename</tt> is a SWIG interface file or a C/C++ header file.
|
|
Below is a subset of <em>options</em> that can be used.
|
|
Additional options are also defined for each target language. A full list
|
|
can be obtained by typing <tt>swig -help</tt> or <tt>swig
|
|
-<em>lang</em> -help</tt>.
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
-allegrocl Generate ALLEGROCL wrappers
|
|
-chicken Generate CHICKEN wrappers
|
|
-clisp Generate CLISP wrappers
|
|
-cffi Generate CFFI wrappers
|
|
-csharp Generate C# wrappers
|
|
-guile Generate Guile wrappers
|
|
-java Generate Java wrappers
|
|
-lua Generate Lua wrappers
|
|
-modula3 Generate Modula 3 wrappers
|
|
-mzscheme Generate Mzscheme wrappers
|
|
-ocaml Generate Ocaml wrappers
|
|
-perl Generate Perl wrappers
|
|
-php4 Generate PHP4 wrappers
|
|
-php5 Generate PHP5 wrappers
|
|
-pike Generate Pike wrappers
|
|
-python Generate Python wrappers
|
|
-r Generate R (aka GNU S) wrappers
|
|
-ruby Generate Ruby wrappers
|
|
-sexp Generate Lisp S-Expressions wrappers
|
|
-tcl Generate Tcl wrappers
|
|
-uffi Generate Common Lisp / UFFI wrappers
|
|
-xml Generate XML wrappers
|
|
|
|
-c++ Enable C++ parsing
|
|
-D<em>symbol</em> Define a preprocessor symbol
|
|
-Fstandard Display error/warning messages in commonly used format
|
|
-Fmicrosoft Display error/warning messages in Microsoft format
|
|
-help Display all options
|
|
-I<em>dir</em> Add a directory to the file include path
|
|
-l<em>file</em> Include a SWIG library file.
|
|
-module <em>name</em> Set the name of the SWIG module
|
|
-o <em>outfile</em> Name of output file
|
|
-outdir <em>dir</em> Set language specific files output directory
|
|
-swiglib Show location of SWIG library
|
|
-version Show SWIG version number
|
|
|
|
</pre></div>
|
|
|
|
<H3><a name="SWIG_nn3"></a>5.1.1 Input format</H3>
|
|
|
|
|
|
<p>
|
|
As input, SWIG expects a file containing ANSI C/C++ declarations and
|
|
special SWIG directives. More often than not, this is a special SWIG
|
|
interface file which is usually denoted with a special <tt>.i</tt> or
|
|
<tt>.swg</tt> suffix. In certain cases, SWIG can be used directly on
|
|
raw header files or source files. However, this is not the most
|
|
typical case and there are several reasons why you might not want to
|
|
do this (described later).
|
|
</p>
|
|
|
|
<p>
|
|
The most common format of a SWIG interface is as follows:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module mymodule
|
|
%{
|
|
#include "myheader.h"
|
|
%}
|
|
// Now list ANSI C/C++ declarations
|
|
int foo;
|
|
int bar(int x);
|
|
...
|
|
</pre></div>
|
|
<p>
|
|
The name of the module is supplied using the special <tt>%module</tt>
|
|
directive (or the <tt>-module</tt> command line option). This
|
|
directive must appear at the beginning of the file and is used to name
|
|
the resulting extension module (in addition, this name often defines
|
|
a namespace in the target language). If the module name is supplied on the
|
|
command line, it overrides the name specified with the
|
|
<tt>%module</tt> directive.
|
|
</p>
|
|
|
|
<p>
|
|
Everything in the <tt>%{ ... %}</tt> block is simply copied verbatim
|
|
to the resulting wrapper file created by SWIG. This section is almost
|
|
always used to include header files and other declarations that are
|
|
required to make the generated wrapper code compile. It is important
|
|
to emphasize that just because you include a declaration in a SWIG
|
|
input file, that declaration does <em>not</em> automatically appear in
|
|
the generated wrapper code---therefore you need to make sure you
|
|
include the proper header files in the <tt>%{ ... %}</tt> section. It
|
|
should be noted that the text enclosed in <tt>%{ ... %}</tt> is not
|
|
parsed or interpreted by SWIG. The <tt>%{...%}</tt> syntax and
|
|
semantics in SWIG is analogous to that of the declarations section
|
|
used in input files to parser generation tools such as yacc or bison.
|
|
</p>
|
|
|
|
<H3><a name="output"></a>5.1.2 SWIG Output</H3>
|
|
|
|
|
|
<p>
|
|
The output of SWIG is a C/C++ file that contains all of the wrapper
|
|
code needed to build an extension module. SWIG may generate some
|
|
additional files depending on the target language. By default, an input file
|
|
with the name <tt>file.i</tt> is transformed into a file
|
|
<tt>file_wrap.c</tt> or <tt>file_wrap.cxx</tt> (depending on whether
|
|
or not the <tt>-c++</tt> option has been used). The name of the
|
|
output file can be changed using the <tt>-o</tt> option. In certain
|
|
cases, file suffixes are used by the compiler to determine the source
|
|
language (C, C++, etc.). Therefore, you have to use the
|
|
<tt>-o</tt> option to change the suffix of the SWIG-generated wrapper
|
|
file if you want something different than the default. For example:
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
$ swig -c++ -python -o example_wrap.cpp example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
The C/C++ output file created by SWIG often
|
|
contains everything that is needed to construct a extension module
|
|
for the target scripting language. SWIG is not a stub compiler nor is it
|
|
usually necessary to edit the output file (and if you look at the output,
|
|
you probably won't want to). To build the final extension module, the
|
|
SWIG output file is compiled and linked with the rest of your C/C++
|
|
program to create a shared library.
|
|
</p>
|
|
|
|
<p>
|
|
Many target languages will also generate proxy class files in the
|
|
target language. The default output directory for these language
|
|
specific files is the same directory as the generated C/C++ file. This can
|
|
can be modified using the <tt>-outdir</tt> option. For example:
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
$ swig -c++ -python -outdir pyfiles -o cppfiles/example_wrap.cpp example.i
|
|
</pre></div>
|
|
<p>
|
|
If the directories <tt>cppfiles</tt> and <tt>pyfiles</tt> exist, the following
|
|
will be generated:</p>
|
|
<div class="shell"><pre>
|
|
cppfiles/example_wrap.cpp
|
|
pyfiles/example.py
|
|
</pre></div>
|
|
|
|
<H3><a name="SWIG_nn5"></a>5.1.3 Comments</H3>
|
|
|
|
|
|
<p>
|
|
C and C++ style comments may appear anywhere in interface files. In
|
|
previous versions of SWIG, comments were used to generate
|
|
documentation files. However, this feature is currently under repair
|
|
and will reappear in a later SWIG release.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn6"></a>5.1.4 C Preprocessor</H3>
|
|
|
|
|
|
<p>
|
|
Like C, SWIG preprocesses all input files through an enhanced version
|
|
of the C preprocessor. All standard preprocessor features are
|
|
supported including file inclusion, conditional compilation and
|
|
macros. However, <tt>#include</tt> statements are ignored unless the
|
|
<tt>-includeall</tt> command line option has been supplied. The
|
|
reason for disabling includes is that SWIG is sometimes used to
|
|
process raw C header files. In this case, you usually only want the
|
|
extension module to include functions in the supplied header file
|
|
rather than everything that might be included by that header file
|
|
(i.e., system headers, C library functions, etc.).
|
|
</p>
|
|
|
|
<p>
|
|
It should also be noted that the SWIG preprocessor skips all text
|
|
enclosed inside a <tt>%{...%}</tt> block. In addition, the
|
|
preprocessor includes a number of macro handling enhancements that
|
|
make it more powerful than the normal C preprocessor. These
|
|
extensions are described in the "<a href="Preprocessor.html#Preprocessor">Preprocessor</a>" chapter.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn7"></a>5.1.5 SWIG Directives</H3>
|
|
|
|
|
|
<p>
|
|
Most of SWIG's operation is controlled by special directives that are
|
|
always preceded by a "<tt>%</tt>" to distinguish them from normal C
|
|
declarations. These directives are used to give SWIG hints or to alter
|
|
SWIG's parsing behavior in some manner.
|
|
</p>
|
|
|
|
<p>
|
|
Since SWIG directives are not legal C syntax, it is generally not
|
|
possible to include them in header files. However, SWIG directives can be
|
|
included in C header files using conditional compilation like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
/* header.h --- Some header file */
|
|
|
|
/* SWIG directives -- only seen if SWIG is running */
|
|
#ifdef SWIG
|
|
%module foo
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<tt>SWIG</tt> is a special preprocessing symbol defined by SWIG when
|
|
it is parsing an input file.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn8"></a>5.1.6 Parser Limitations</H3>
|
|
|
|
|
|
<p>
|
|
Although SWIG can parse most C/C++ declarations, it does not
|
|
provide a complete C/C++ parser implementation. Most of these
|
|
limitations pertain to very complicated type declarations and certain
|
|
advanced C++ features. Specifically, the following features are not
|
|
currently supported:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>Non-conventional type declarations.
|
|
For example, SWIG does not support declarations such as the following
|
|
(even though this is legal C):
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Non-conventional placement of storage specifier (extern) */
|
|
const int extern Number;
|
|
|
|
/* Extra declarator grouping */
|
|
Matrix (foo); // A global variable
|
|
|
|
/* Extra declarator grouping in parameters */
|
|
void bar(Spam (Grok)(Doh));
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In practice, few (if any) C programmers actually write code like
|
|
this since this style is never featured in programming books. However,
|
|
if you're feeling particularly obfuscated, you can certainly break SWIG (although why would you want to?).
|
|
</p>
|
|
</li>
|
|
|
|
<li>Running SWIG on C++ source files (what would appear in a .C or .cxx file)
|
|
is not recommended. Even though SWIG can parse C++ class declarations,
|
|
it ignores declarations that are decoupled from their
|
|
original class definition (the declarations are parsed, but a lot of warning
|
|
messages may be generated). For example:
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Not supported by SWIG */
|
|
int foo::bar(int) {
|
|
... whatever ...
|
|
}
|
|
</pre>
|
|
</div>
|
|
</li>
|
|
|
|
<li>Certain advanced features of C++ such as nested classes
|
|
are not yet supported. Please see the section on using SWIG
|
|
with C++ for more information.
|
|
</ul>
|
|
|
|
<p>
|
|
In the event of a parsing error, conditional compilation can be used to skip
|
|
offending code. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#ifndef SWIG
|
|
... some bad declarations ...
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
Alternatively, you can just delete the offending code from the interface file.
|
|
</p>
|
|
|
|
<p>
|
|
One of the reasons why SWIG does not provide a full C++ parser
|
|
implementation is that it has been designed to work with incomplete
|
|
specifications and to be very permissive in its handling of C/C++
|
|
datatypes (e.g., SWIG can generate interfaces even when there are
|
|
missing class declarations or opaque datatypes). Unfortunately, this
|
|
approach makes it extremely difficult to implement certain parts of a
|
|
C/C++ parser as most compilers use type information to assist in the
|
|
parsing of more complex declarations (for the truly curious, the
|
|
primary complication in the implementation is that the SWIG parser
|
|
does not utilize a separate <em>typedef-name</em> terminal symbol as
|
|
described on p. 234 of K&R).
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn9"></a>5.2 Wrapping Simple C Declarations</H2>
|
|
|
|
|
|
<p>
|
|
SWIG wraps simple C declarations by creating an interface that closely matches
|
|
the way in which the declarations would be used in a C program.
|
|
For example, consider the following interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
extern double sin(double x);
|
|
extern int strcmp(const char *, const char *);
|
|
extern int Foo;
|
|
%}
|
|
#define STATUS 50
|
|
#define VERSION "1.1"
|
|
</pre></div>
|
|
<p>
|
|
In this file, there are two functions <tt>sin()</tt> and <tt>strcmp()</tt>,
|
|
a global variable <tt>Foo</tt>, and two constants <tt>STATUS</tt> and
|
|
<tt>VERSION</tt>. When SWIG creates an extension module, these
|
|
declarations are accessible as scripting language functions, variables, and
|
|
constants respectively. For example, in Tcl:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
% sin 3
|
|
5.2335956
|
|
% strcmp Dave Mike
|
|
-1
|
|
% puts $Foo
|
|
42
|
|
% puts $STATUS
|
|
50
|
|
% puts $VERSION
|
|
1.1
|
|
</pre></div>
|
|
<p>
|
|
Or in Python:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
>>> example.sin(3)
|
|
5.2335956
|
|
>>> example.strcmp('Dave','Mike')
|
|
-1
|
|
>>> print example.cvar.Foo
|
|
42
|
|
>>> print example.STATUS
|
|
50
|
|
>>> print example.VERSION
|
|
1.1
|
|
</pre></div>
|
|
<p>
|
|
Whenever possible, SWIG creates an interface that closely matches the underlying C/C++
|
|
code. However, due to subtle differences between languages, run-time
|
|
environments, and semantics, it is not always possible to do so. The
|
|
next few sections describes various aspects of this mapping.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn10"></a>5.2.1 Basic Type Handling</H3>
|
|
|
|
|
|
<p>
|
|
In order to build an interface, SWIG has to convert C/C++ datatypes to
|
|
equivalent types in the target language. Generally,
|
|
scripting languages provide a more limited set of primitive types than C.
|
|
Therefore, this conversion process involves a certain amount of type
|
|
coercion.
|
|
</p>
|
|
|
|
<p>
|
|
Most scripting languages provide a single integer type that is implemented using
|
|
the <tt>int</tt> or <tt>long</tt> datatype in C. The following list shows
|
|
all of the C datatypes that SWIG will convert to and from integers in the target language:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
int
|
|
short
|
|
long
|
|
unsigned
|
|
signed
|
|
unsigned short
|
|
unsigned long
|
|
unsigned char
|
|
signed char
|
|
bool
|
|
</pre></div>
|
|
|
|
<p>
|
|
When an integral value is converted from C, a cast is used to convert it to
|
|
the representation in the target language.
|
|
Thus, a 16 bit short in C may be promoted to a 32 bit integer. When integers are
|
|
converted in the other direction, the value is cast back into the original C type.
|
|
If the value is too large to fit, it is silently truncated.
|
|
<!-- Dave: Maybe we should fix this -->
|
|
</p>
|
|
|
|
<p>
|
|
<tt>unsigned char</tt> and <tt>signed char</tt> are special cases that
|
|
are handled as small 8-bit integers. Normally, the <tt>char</tt>
|
|
datatype is mapped as a one-character ASCII string. </p>
|
|
|
|
<p>
|
|
The <tt>bool</tt> datatype is cast to and from an integer value of 0
|
|
and 1 unless the target language provides a special boolean type.</p>
|
|
|
|
<p>
|
|
Some care is required when working with large integer values. Most
|
|
scripting languages use 32-bit integers so mapping a 64-bit long
|
|
integer may lead to truncation errors. Similar problems may arise with
|
|
32 bit unsigned integers (which may appear as large negative
|
|
numbers). As a rule of thumb, the <tt>int</tt> datatype and all
|
|
variations of <tt>char</tt> and <tt>short</tt> datatypes are safe to
|
|
use. For <tt>unsigned int</tt> and <tt>long</tt> datatypes, you will
|
|
need to carefully check the correct operation of your program after
|
|
it has been wrapped with SWIG.
|
|
</p>
|
|
|
|
<p>
|
|
Although the SWIG parser supports the <tt>long long</tt> datatype, not
|
|
all language modules support it. This is because <tt>long long</tt>
|
|
usually exceeds the integer precision available in the target
|
|
language. In certain modules such as Tcl and Perl5, <tt>long
|
|
long</tt> integers are encoded as strings. This allows the full range
|
|
of these numbers to be represented. However, it does not allow
|
|
<tt>long long</tt> values to be used in arithmetic expressions. It
|
|
should also be noted that although <tt>long long</tt> is part
|
|
of the ISO C99 standard, it is not universally supported by all C
|
|
compilers. Make sure you are using a compiler that supports <tt>long
|
|
long</tt> before trying to use this type with SWIG.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG recognizes the following floating point types :</p>
|
|
|
|
<div class="code"><pre>
|
|
float
|
|
double
|
|
</pre></div>
|
|
|
|
<p>
|
|
Floating point numbers are mapped to and from the natural
|
|
representation of floats in the target language. This is almost always
|
|
a C <tt>double</tt>. The rarely used datatype of <tt>long double</tt>
|
|
is not supported by SWIG.</p>
|
|
|
|
<p>
|
|
The <tt>char</tt> datatype is mapped into a NULL terminated ASCII
|
|
string with a single character. When used in a scripting language it
|
|
shows up as a tiny string containing the character value. When
|
|
converting the value back into C, SWIG takes a character string
|
|
from the scripting language and strips off the first character as the
|
|
char value. Thus if the value "foo" is assigned to a
|
|
<tt>char</tt> datatype, it gets the value `f'.</p>
|
|
|
|
<p>
|
|
The <tt>char *</tt> datatype is handled as a NULL-terminated ASCII
|
|
string. SWIG maps this into a 8-bit character string in the target
|
|
scripting language. SWIG converts character strings in the target
|
|
language to NULL terminated strings before passing them into
|
|
C/C++. The default handling of these strings does not allow them to
|
|
have embedded NULL bytes. Therefore, the <tt>char *</tt> datatype is
|
|
not generally suitable for passing binary data. However, it is
|
|
possible to change this behavior by defining a SWIG typemap. See the chapter
|
|
on <a href="Typemaps.html#Typemaps">Typemaps</a> for details about this.
|
|
</p>
|
|
|
|
<p>
|
|
At this time, SWIG provides limited support for Unicode and
|
|
wide-character strings (the C <tt>wchar_t</tt> type).
|
|
Some languages provide typemaps for wchar_t, but bear in mind these
|
|
might not be portable across different operating systems. This is a
|
|
delicate topic that is poorly understood by many programmers and not
|
|
implemented in a consistent manner across languages. For those
|
|
scripting languages that provide Unicode support, Unicode strings are
|
|
often available in an 8-bit representation such as UTF-8 that can be
|
|
mapped to the <tt>char *</tt> type (in which case the SWIG interface
|
|
will probably work). If the program you are wrapping uses Unicode,
|
|
there is no guarantee that Unicode characters in the target language
|
|
will use the same internal representation (e.g., UCS-2 vs. UCS-4).
|
|
You may need to write some special conversion functions.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn11"></a>5.2.2 Global Variables</H3>
|
|
|
|
|
|
<p>
|
|
Whenever possible, SWIG maps C/C++ global variables into scripting language
|
|
variables. For example,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
double foo;
|
|
|
|
</pre></div>
|
|
<p>
|
|
results in a scripting language variable like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
# Tcl
|
|
set foo [3.5] ;# Set foo to 3.5
|
|
puts $foo ;# Print the value of foo
|
|
|
|
# Python
|
|
cvar.foo = 3.5 # Set foo to 3.5
|
|
print cvar.foo # Print value of foo
|
|
|
|
# Perl
|
|
$foo = 3.5; # Set foo to 3.5
|
|
print $foo,"\n"; # Print value of foo
|
|
|
|
# Ruby
|
|
Module.foo = 3.5 # Set foo to 3.5
|
|
print Module.foo, "\n" # Print value of foo
|
|
</pre></div>
|
|
<p>
|
|
Whenever the scripting language variable is used, the underlying C
|
|
global variable is accessed. Although SWIG makes every
|
|
attempt to make global variables work like scripting language
|
|
variables, it is not always possible to do so. For instance, in
|
|
Python, all global variables must be accessed through a special
|
|
variable object known as <tt>cvar</tt> (shown above). In Ruby, variables are
|
|
accessed as attributes of the module. Other languages may
|
|
convert variables to a pair of accessor functions. For example, the
|
|
Java module generates a pair of functions <tt>double get_foo()</tt>
|
|
and <tt>set_foo(double val)</tt> that are used to manipulate the
|
|
value.
|
|
</p>
|
|
|
|
<p>
|
|
Finally, if a global variable has been declared as <tt>const</tt>, it
|
|
only supports read-only access. Note: this behavior is new to SWIG-1.3.
|
|
Earlier versions of SWIG incorrectly handled <tt>const</tt> and created
|
|
constants instead.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn12"></a>5.2.3 Constants</H3>
|
|
|
|
|
|
<p>
|
|
Constants can be created using <tt>#define</tt>, enumerations,
|
|
or a special <tt>%constant</tt> directive. The following
|
|
interface file shows a few valid constant declarations :</p>
|
|
|
|
<div class="code"><pre>
|
|
#define I_CONST 5 // An integer constant
|
|
#define PI 3.14159 // A Floating point constant
|
|
#define S_CONST "hello world" // A string constant
|
|
#define NEWLINE '\n' // Character constant
|
|
|
|
enum boolean {NO=0, YES=1};
|
|
enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
|
|
SEP, OCT, NOV, DEC};
|
|
%constant double BLAH = 42.37;
|
|
#define F_CONST (double) 5 // A floating pointer constant with cast
|
|
#define PI_4 PI/4
|
|
#define FLAGS 0x04 | 0x08 | 0x40
|
|
|
|
</pre></div>
|
|
<p>
|
|
In <tt>#define</tt> declarations, the type of a constant is inferred
|
|
by syntax. For example, a number with a decimal point is assumed to be
|
|
floating point. In addition, SWIG must be able to fully resolve all
|
|
of the symbols used in a <tt>#define</tt> in order for a constant to
|
|
actually be created. This restriction is necessary because
|
|
<tt>#define</tt> is also used to define preprocessor macros that are
|
|
definitely not meant to be part of the scripting language interface.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define EXTERN extern
|
|
|
|
EXTERN void foo();
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
In this case, you probably don't want to create a constant called
|
|
<tt>EXTERN</tt> (what would the value be?). In general,
|
|
SWIG will not create constants for macros unless the value can
|
|
be completely determined by the preprocessor. For instance, in the above example,
|
|
the declaration
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define PI_4 PI/4
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
defines a constant because <tt>PI</tt> was already defined as a
|
|
constant and the value is known.
|
|
</p>
|
|
|
|
<p>
|
|
The use of constant expressions is allowed, but SWIG does not evaluate
|
|
them. Rather, it passes them through to the output file and lets the C
|
|
compiler perform the final evaluation (SWIG does perform a limited
|
|
form of type-checking however).</p>
|
|
|
|
<p>
|
|
For enumerations, it is critical that the original enum definition be
|
|
included somewhere in the interface file (either in a header file or
|
|
in the <tt>%{,%}</tt> block). SWIG only translates the enumeration
|
|
into code needed to add the constants to a scripting language. It
|
|
needs the original enumeration declaration in order to get the correct
|
|
enum values as assigned by the C compiler.
|
|
</p>
|
|
|
|
<p>
|
|
The <tt>%constant</tt> directive is used to more precisely create
|
|
constants corresponding to different C datatypes. Although it is not
|
|
usually not needed for simple values, it is more useful when working
|
|
with pointers and other more complex datatypes. Typically, <tt>%constant</tt>
|
|
is only used when you want to add constants to the scripting language
|
|
interface that are not defined in the original header file.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn13"></a>5.2.4 A brief word about <tt>const</tt></H3>
|
|
|
|
|
|
<p>
|
|
A common confusion with C programming is the semantic meaning of the
|
|
<tt>const</tt> qualifier in declarations--especially when it is mixed
|
|
with pointers and other type modifiers. In fact, previous versions of SWIG
|
|
handled <tt>const</tt> incorrectly--a situation that SWIG-1.3.7 and newer
|
|
releases have fixed.
|
|
</p>
|
|
|
|
<p>
|
|
Starting with SWIG-1.3, all variable declarations, regardless of any
|
|
use of <tt>const</tt>, are wrapped as global variables. If a
|
|
declaration happens to be declared as <tt>const</tt>, it is wrapped as
|
|
a read-only variable. To tell if a variable is <tt>const</tt> or not,
|
|
you need to look at the right-most occurrence of the <tt>const</tt>
|
|
qualifier (that appears before the variable name). If the right-most
|
|
<tt>const</tt> occurs after all other type modifiers (such as
|
|
pointers), then the variable is <tt>const</tt>. Otherwise, it is not.
|
|
</p>
|
|
|
|
<p>
|
|
Here are some examples of <tt>const</tt> declarations.
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
const char a; // A constant character
|
|
char const b; // A constant character (the same)
|
|
char *const c; // A constant pointer to a character
|
|
const char *const d; // A constant pointer to a constant character
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
Here is an example of a declaration that is not <tt>const</tt>:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
const char *e; // A pointer to a constant character. The pointer
|
|
// may be modified.
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
In this case, the pointer <tt>e</tt> can change---it's only the value
|
|
being pointed to that is read-only.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility Note:</b> One reason for changing SWIG to handle
|
|
<tt>const</tt> declarations as read-only variables is that there are
|
|
many situations where the value of a <tt>const</tt> variable might
|
|
change. For example, a library might export a symbol as
|
|
<tt>const</tt> in its public API to discourage modification, but still
|
|
allow the value to change through some other kind of internal
|
|
mechanism. Furthermore, programmers often overlook the fact that with
|
|
a constant declaration like <tt>char *const</tt>, the underlying data
|
|
being pointed to can be modified--it's only the pointer itself that is
|
|
constant. In an embedded system, a <tt>const</tt> declaration might
|
|
refer to a read-only memory address such as the location of a
|
|
memory-mapped I/O device port (where the value changes, but writing to
|
|
the port is not supported by the hardware). Rather than trying to
|
|
build a bunch of special cases into the <tt>const</tt> qualifier, the
|
|
new interpretation of <tt>const</tt> as "read-only" is simple and
|
|
exactly matches the actual semantics of <tt>const</tt> in C/C++. If
|
|
you really want to create a constant as in older versions of SWIG, use
|
|
the <tt>%constant</tt> directive instead. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%constant double PI = 3.14159;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
or
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#ifdef SWIG
|
|
#define const %constant
|
|
#endif
|
|
const double foo = 3.4;
|
|
const double bar = 23.4;
|
|
const int spam = 42;
|
|
#ifdef SWIG
|
|
#undef const
|
|
#endif
|
|
...
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="SWIG_nn14"></a>5.2.5 A cautionary tale of <tt>char *</tt></H3>
|
|
|
|
|
|
<p>
|
|
Before going any further, there is one bit of caution involving
|
|
<tt>char *</tt> that must now be mentioned. When strings are passed
|
|
from a scripting language to a C <tt>char *</tt>, the pointer usually
|
|
points to string data stored inside the interpreter. It is almost
|
|
always a really bad idea to modify this data. Furthermore, some
|
|
languages may explicitly disallow it. For instance, in Python,
|
|
strings are supposed be immutable. If you violate this, you will probably
|
|
receive a vast amount of wrath when you unleash your module on the world.
|
|
</p>
|
|
|
|
<p>
|
|
The primary source of problems are functions that might modify string data in place.
|
|
A classic example would be a function like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char *strcat(char *s, const char *t)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Although SWIG will certainly generate a wrapper for this, its behavior
|
|
will be undefined. In fact, it will probably cause your application
|
|
to crash with a segmentation fault or other memory related problem.
|
|
This is because <tt>s</tt> refers to some internal data in the target
|
|
language---data that you shouldn't be touching.
|
|
</p>
|
|
|
|
<p>
|
|
The bottom line: don't rely on <tt>char *</tt> for anything other than read-only
|
|
input values. However, it must be noted that you could change the behavior of SWIG
|
|
using <a href="Typemaps.html#Typemaps">typemaps</a>.
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn15"></a>5.3 Pointers and complex objects</H2>
|
|
|
|
|
|
<p>
|
|
Most C programs manipulate arrays, structures, and other types of objects. This section
|
|
discusses the handling of these datatypes.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn16"></a>5.3.1 Simple pointers</H3>
|
|
|
|
|
|
<p>
|
|
Pointers to primitive C datatypes such as </p>
|
|
|
|
<div class="code"><pre>
|
|
int *
|
|
double ***
|
|
char **
|
|
</pre></div>
|
|
<p>
|
|
are fully supported by SWIG. Rather than trying to convert the data being pointed to into a scripting
|
|
representation, SWIG simply encodes the pointer itself into a
|
|
representation that contains the actual value of the pointer and a type-tag.
|
|
Thus, the SWIG representation of the above
|
|
pointers (in Tcl), might look like this:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
_10081012_p_int
|
|
_1008e124_ppp_double
|
|
_f8ac_pp_char
|
|
</pre></div>
|
|
|
|
<p>
|
|
A NULL pointer is represented by the string "NULL" or the value 0
|
|
encoded with type information.</p>
|
|
|
|
<p>
|
|
All pointers are treated as opaque objects by SWIG. Thus, a pointer
|
|
may be returned by a function and passed around to other C functions
|
|
as needed. For all practical purposes, the scripting language
|
|
interface works in exactly the same way as you would use the
|
|
pointer in a C program. The only difference is that there is no mechanism for
|
|
dereferencing the pointer since this would require the target language
|
|
to understand the memory layout of the underlying object.
|
|
</p>
|
|
|
|
<p>
|
|
The scripting language representation of a pointer value should never be
|
|
manipulated directly. Even though the values shown look like hexadecimal
|
|
addresses, the numbers used may differ from the actual machine address (e.g.,
|
|
on little-endian machines, the digits may appear in reverse order).
|
|
Furthermore, SWIG does not
|
|
normally map pointers into high-level objects such as associative
|
|
arrays or lists (for example, converting an
|
|
<tt>int *</tt> into an list of integers). There are several reasons
|
|
why SWIG does not do this:</p>
|
|
|
|
<ul>
|
|
<li>There is not enough information in a C declaration to properly map
|
|
pointers into higher level constructs. For example, an <tt>int *</tt>
|
|
may indeed be an array of integers, but if it contains ten million
|
|
elements, converting it into a list object is probably a bad idea.
|
|
</li>
|
|
|
|
<li>The underlying semantics associated with a pointer is not known
|
|
by SWIG. For instance, an <tt>int *</tt> might not be an array at all--perhaps it
|
|
is an output value!
|
|
</li>
|
|
|
|
<li>By handling all pointers in a consistent manner, the implementation of SWIG is greatly
|
|
simplified and less prone to error.
|
|
</li>
|
|
</ul>
|
|
|
|
<H3><a name="SWIG_nn17"></a>5.3.2 Run time pointer type checking</H3>
|
|
|
|
|
|
<p>
|
|
By allowing pointers to be manipulated from a scripting language, extension modules
|
|
effectively bypass compile-time type checking in the C/C++
|
|
compiler. To prevent errors, a type signature is encoded into all
|
|
pointer values and is used to perform run-time type checking. This
|
|
type-checking process is an integral part of SWIG and can not be
|
|
disabled or modified without using typemaps (described in later
|
|
chapters).
|
|
</p>
|
|
|
|
<p>
|
|
Like C, <tt>void *</tt> matches any kind of pointer. Furthermore,
|
|
<tt>NULL</tt> pointers can be passed to any function that expects to
|
|
receive a pointer. Although this has the potential to cause a crash,
|
|
<tt>NULL</tt> pointers are also sometimes used
|
|
as sentinel values or to denote a missing/empty value. Therefore,
|
|
SWIG leaves NULL pointer checking up to the application.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn18"></a>5.3.3 Derived types, structs, and classes</H3>
|
|
|
|
|
|
<p>
|
|
For everything else (structs, classes, arrays, etc...) SWIG applies a
|
|
very simple rule :</p>
|
|
|
|
<center>
|
|
<b>Everything else is a pointer</b>
|
|
</center>
|
|
|
|
<p>
|
|
In other words, SWIG manipulates everything else by reference. This
|
|
model makes sense because most C/C++ programs make heavy use of
|
|
pointers and SWIG can use the type-checked pointer mechanism already
|
|
present for handling pointers to basic datatypes.</p>
|
|
|
|
<p>
|
|
Although this probably sounds complicated, it's really quite
|
|
simple. Suppose you have an interface file like this :</p>
|
|
|
|
<div class="code"><pre>
|
|
%module fileio
|
|
FILE *fopen(char *, char *);
|
|
int fclose(FILE *);
|
|
unsigned fread(void *ptr, unsigned size, unsigned nobj, FILE *);
|
|
unsigned fwrite(void *ptr, unsigned size, unsigned nobj, FILE *);
|
|
void *malloc(int nbytes);
|
|
void free(void *);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this file, SWIG doesn't know what a <tt>FILE</tt> is, but since it's used
|
|
as a pointer, so it doesn't really matter what it is. If you wrapped
|
|
this module into Python, you can use the functions just like you
|
|
expect :</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Copy a file
|
|
def filecopy(source,target):
|
|
f1 = fopen(source,"r")
|
|
f2 = fopen(target,"w")
|
|
buffer = malloc(8192)
|
|
nbytes = fread(buffer,8192,1,f1)
|
|
while (nbytes > 0):
|
|
fwrite(buffer,8192,1,f2)
|
|
nbytes = fread(buffer,8192,1,f1)
|
|
free(buffer)
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case <tt>f1</tt>,<tt> f2</tt>, and <tt>buffer</tt> are all
|
|
opaque objects containing C pointers. It doesn't matter what value
|
|
they contain--our program works just fine without this knowledge.</p>
|
|
|
|
<H3><a name="SWIG_nn19"></a>5.3.4 Undefined datatypes</H3>
|
|
|
|
|
|
<p>
|
|
When SWIG encounters an undeclared datatype, it automatically assumes
|
|
that it is a structure or class. For example, suppose the following
|
|
function appeared in a SWIG input file:</p>
|
|
|
|
<div class="code"><pre>
|
|
void matrix_multiply(Matrix *a, Matrix *b, Matrix *c);
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG has no idea what a "<tt>Matrix</tt>" is. However, it is obviously
|
|
a pointer to something so SWIG generates a wrapper using its generic pointer
|
|
handling code.
|
|
</p>
|
|
|
|
<p>
|
|
Unlike C or C++, SWIG does not actually care whether <tt>Matrix</tt>
|
|
has been previously defined in the interface file or not. This
|
|
allows SWIG to generate interfaces from
|
|
only partial or limited information. In some cases, you may not care
|
|
what a <tt>Matrix</tt> really is as long as you can pass an opaque reference to
|
|
one around in the scripting language interface.
|
|
</p>
|
|
|
|
<p>
|
|
An important detail to mention is that SWIG will gladly generate
|
|
wrappers for an interface when there are unspecified type names.
|
|
However, <b>all unspecified types are internally handled as pointers
|
|
to structures or classes!</b> For example, consider the following declaration:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void foo(size_t num);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If <tt>size_t</tt> is undeclared, SWIG generates wrappers
|
|
that expect to receive a type of <tt>size_t *</tt> (this mapping is described shortly).
|
|
As a result, the scripting interface might behave strangely. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
foo(40);
|
|
TypeError: expected a _p_size_t.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The only way to fix this problem is to make sure you properly declare type names using
|
|
<tt>typedef</tt>.
|
|
</p>
|
|
|
|
<!-- We might want to add an error reporting flag to swig -->
|
|
|
|
<H3><a name="SWIG_nn20"></a>5.3.5 Typedef</H3>
|
|
|
|
|
|
<p>
|
|
Like C, <tt>typedef</tt> can be used to define new type names in SWIG. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
typedef unsigned int size_t;
|
|
</pre></div>
|
|
|
|
<p>
|
|
<tt>typedef</tt> definitions appearing in a SWIG interface
|
|
are not propagated to the generated wrapper code. Therefore, they
|
|
either need to be defined in an included header file or placed in the
|
|
declarations section like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
/* Include in the generated wrapper file */
|
|
typedef unsigned int size_t;
|
|
%}
|
|
/* Tell SWIG about it */
|
|
typedef unsigned int size_t;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
or
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
typedef unsigned int size_t;
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In certain cases, you might be able to include other header files to collect type information.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%import "sys/types.h"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, you might run SWIG as follows:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -I/usr/include -includeall example.i
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
It should be noted that your mileage will vary greatly here.
|
|
System headers are notoriously complicated and may rely upon a variety
|
|
of non-standard C coding extensions (e.g., such as special directives
|
|
to GCC). Unless you exactly specify the right include directories and
|
|
preprocessor symbols, this may not work correctly (you will have to
|
|
experiment).
|
|
</p>
|
|
|
|
<p>
|
|
SWIG tracks <tt>typedef</tt> declarations and uses this information
|
|
for run-time type checking. For instance, if you use the above <tt>typedef</tt> and
|
|
had the following function declaration:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void foo(unsigned int *ptr);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The corresponding wrapper function will accept arguments of
|
|
type <tt>unsigned int *</tt> or <tt>size_t *</tt>.
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn21"></a>5.4 Other Practicalities</H2>
|
|
|
|
|
|
<p>
|
|
So far, this chapter has presented almost everything you need to know to use SWIG
|
|
for simple interfaces. However, some C programs use idioms that are somewhat
|
|
more difficult to map to a scripting language interface. This section describes
|
|
some of these issues.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn22"></a>5.4.1 Passing structures by value</H3>
|
|
|
|
|
|
<p>
|
|
Sometimes a C function takes structure parameters that are passed
|
|
by value. For example, consider the following function:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
double dot_product(Vector a, Vector b);
|
|
</pre></div>
|
|
|
|
<p>
|
|
To deal with this, SWIG transforms the function to use pointers by
|
|
creating a wrapper equivalent to the following:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
double wrap_dot_product(Vector *a, Vector *b) {
|
|
Vector x = *a;
|
|
Vector y = *b;
|
|
return dot_product(x,y);
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
In the target language, the <tt>dot_product()</tt> function now accepts pointers
|
|
to Vectors instead of Vectors. For the most part, this transformation
|
|
is transparent so you might not notice.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn23"></a>5.4.2 Return by value</H3>
|
|
|
|
|
|
<p>
|
|
C functions that return structures or classes datatypes by value are more difficult
|
|
to handle. Consider the following function:</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector cross_product(Vector v1, Vector v2);
|
|
</pre></div>
|
|
|
|
<p>
|
|
This function wants to return <tt>Vector</tt>, but SWIG only really supports
|
|
pointers. As a result, SWIG creates a wrapper like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *wrap_cross_product(Vector *v1, Vector *v2) {
|
|
Vector x = *v1;
|
|
Vector y = *v2;
|
|
Vector *result;
|
|
result = (Vector *) malloc(sizeof(Vector));
|
|
*(result) = cross(x,y);
|
|
return result;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
or if SWIG was run with the <tt>-c++</tt> option:</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *wrap_cross(Vector *v1, Vector *v2) {
|
|
Vector x = *v1;
|
|
Vector y = *v2;
|
|
Vector *result = new Vector(cross(x,y)); // Uses default copy constructor
|
|
return result;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
In both cases, SWIG allocates a new object and returns a reference to it. It
|
|
is up to the user to delete the returned object when it is no longer
|
|
in use. Clearly, this will leak memory if you are unaware of the implicit
|
|
memory allocation and don't take steps to free the result. That said, it should be
|
|
noted that some language modules can now automatically track newly created objects and
|
|
reclaim memory for you. Consult the documentation for each language module for more details.
|
|
</p>
|
|
|
|
<p>
|
|
It should also be noted that the handling of pass/return by value in
|
|
C++ has some special cases. For example, the above code fragments
|
|
don't work correctly if <tt>Vector</tt> doesn't define a default
|
|
constructor. The section on SWIG and C++ has more information about this case.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn24"></a>5.4.3 Linking to structure variables</H3>
|
|
|
|
|
|
<p>
|
|
When global variables or class members involving structures are
|
|
encountered, SWIG handles them as pointers. For example, a global
|
|
variable like this</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector unit_i;
|
|
</pre></div>
|
|
|
|
<p>
|
|
gets mapped to an underlying pair of set/get functions like this :</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *unit_i_get() {
|
|
return &unit_i;
|
|
}
|
|
void unit_i_set(Vector *value) {
|
|
unit_i = *value;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
Again some caution is in order. A global variable created in this
|
|
manner will show up as a pointer in the target scripting language. It
|
|
would be an extremely bad idea to free or destroy such a pointer. Also,
|
|
C++ classes must supply a properly defined copy constructor in order for
|
|
assignment to work correctly.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn25"></a>5.4.4 Linking to <tt>char *</tt></H3>
|
|
|
|
|
|
<p>
|
|
When a global variable of type <tt>char *</tt> appears, SWIG uses <tt>malloc()</tt> or
|
|
<tt>new</tt> to allocate memory for the new value. Specifically, if you have a variable
|
|
like this
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char *foo;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
SWIG generates the following code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* C mode */
|
|
void foo_set(char *value) {
|
|
if (foo) free(foo);
|
|
foo = (char *) malloc(strlen(value)+1);
|
|
strcpy(foo,value);
|
|
}
|
|
|
|
/* C++ mode. When -c++ option is used */
|
|
void foo_set(char *value) {
|
|
if (foo) delete [] foo;
|
|
foo = new char[strlen(value)+1];
|
|
strcpy(foo,value);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If this is not the behavior that you want, consider making the variable read-only using the
|
|
<tt>%immutable</tt> directive. Alternatively, you might write a short assist-function to set the value
|
|
exactly like you want. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
void set_foo(char *value) {
|
|
strncpy(foo,value, 50);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Note: If you write an assist function like this, you will have to call
|
|
it as a function from the target scripting language (it does not work
|
|
like a variable). For example, in Python you will have to write:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> set_foo("Hello World")
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
A common mistake with <tt>char *</tt> variables is to link to a variable declared like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char *VERSION = "1.0";
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, the variable will be readable, but any attempt to change
|
|
the value results in a segmentation or general protection fault. This
|
|
is due to the fact that SWIG is trying to release the old value using
|
|
<tt>free</tt> or <tt>delete</tt> when the string literal value currently assigned to the variable wasn't
|
|
allocated using <tt>malloc()</tt> or <tt>new</tt>.
|
|
To fix this behavior, you can
|
|
either mark the variable as read-only, write a typemap (as described in Chapter 6),
|
|
or write a special set function as shown. Another alternative is to declare the
|
|
variable as an array:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char VERSION[64] = "1.0";
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When variables of type <tt>const char *</tt> are declared, SWIG still generates functions for setting and
|
|
getting the value. However, the default behavior does <em>not</em> release the previous contents (resulting in
|
|
a possible memory leak). In fact, you may get a warning message such as this when wrapping such a variable:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
example.i:20. Typemap warning. Setting const char * variable may leak memory
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The reason for this behavior is that <tt>const char *</tt> variables are often used to point to string literals.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
const char *foo = "Hello World\n";
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Therefore, it's a really bad idea to call <tt>free()</tt> on such a
|
|
pointer. On the other hand, it <em>is</em> legal to change the
|
|
pointer to point to some other value. When setting a variable of this
|
|
type, SWIG allocates a new string (using malloc or new) and changes
|
|
the pointer to point to the new value. However, repeated
|
|
modifications of the value will result in a memory leak since the old
|
|
value is not released.
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<H3><a name="SWIG_nn26"></a>5.4.5 Arrays</H3>
|
|
|
|
|
|
<p>
|
|
Arrays are fully supported by SWIG, but they are always handled as pointers instead
|
|
of mapping them to a special array object or list in the target language. Thus, the
|
|
following declarations :</p>
|
|
|
|
<div class="code"><pre>
|
|
int foobar(int a[40]);
|
|
void grok(char *argv[]);
|
|
void transpose(double a[20][20]);
|
|
</pre></div>
|
|
|
|
<p>
|
|
are processed as if they were really declared like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
int foobar(int *a);
|
|
void grok(char **argv);
|
|
void transpose(double (*a)[20]);
|
|
</pre></div>
|
|
|
|
<p>
|
|
Like C, SWIG does not perform array bounds checking.
|
|
It is up to the
|
|
user to make sure the pointer points a suitably allocated region of memory.
|
|
</p>
|
|
|
|
<p>
|
|
Multi-dimensional arrays are transformed into a pointer to an array of one less
|
|
dimension. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int [10]; // Maps to int *
|
|
int [10][20]; // Maps to int (*)[20]
|
|
int [10][20][30]; // Maps to int (*)[20][30]
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
It is important to note that in the C type system, a multidimensional
|
|
array <tt>a[][]</tt> is <b>NOT</b> equivalent to a single pointer
|
|
<tt>*a</tt> or a double pointer such as <tt>**a</tt>. Instead, a
|
|
pointer to an array is used (as shown above) where the actual value of
|
|
the pointer is the starting memory location of the array. The
|
|
reader is strongly advised to dust off their C book and re-read the
|
|
section on arrays before using them with SWIG.
|
|
</p>
|
|
|
|
<p>
|
|
Array variables are supported, but are read-only by default. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int a[100][200];
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, reading the variable 'a' returns a pointer of type <tt>int (*)[200]</tt>
|
|
that points to the first element of the array <tt>&a[0][0]</tt>. Trying to modify 'a' results
|
|
in an error. This is because SWIG does not know how to copy data from the target
|
|
language into the array. To work around this limitation, you may want to write
|
|
a few simple assist functions like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
void a_set(int i, int j, int val) {
|
|
a[i][j] = val;
|
|
}
|
|
int a_get(int i, int j) {
|
|
return a[i][j];
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To dynamically create arrays of various sizes and shapes, it may be useful to write
|
|
some helper functions in your interface. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// Some array helpers
|
|
%inline %{
|
|
/* Create any sort of [size] array */
|
|
int *int_array(int size) {
|
|
return (int *) malloc(size*sizeof(int));
|
|
}
|
|
/* Create a two-dimension array [size][10] */
|
|
int (*int_array_10(int size))[10] {
|
|
return (int (*)[10]) malloc(size*10*sizeof(int));
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Arrays of <tt>char</tt> are handled as a special case by SWIG. In this case, strings in the
|
|
target language can be stored in the array. For example, if you have a declaration like this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char pathname[256];
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
SWIG generates functions for both getting and setting the value that are equivalent to the following
|
|
code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char *pathname_get() {
|
|
return pathname;
|
|
}
|
|
void pathname_set(char *value) {
|
|
strncpy(pathname,value,256);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In the target language, the value can be set like a normal variable.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_readonly_variables"></a>5.4.6 Creating read-only variables</H3>
|
|
|
|
|
|
<p>
|
|
A read-only variable can be created by using the <tt>%immutable</tt>
|
|
directive as shown :</p>
|
|
|
|
<div class="code"><pre>
|
|
// File : interface.i
|
|
|
|
int a; // Can read/write
|
|
%immutable;
|
|
int b,c,d // Read only variables
|
|
%mutable;
|
|
double x,y // read/write
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>%immutable</tt> directive enables read-only mode until it is
|
|
explicitly disabled using the <tt>%mutable</tt> directive. As an alternative to turning
|
|
read-only mode off and on like this, individual declarations can also be tagged as
|
|
immutable. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%immutable x; // Make x read-only
|
|
...
|
|
double x; // Read-only (from earlier %immutable directive)
|
|
double y; // Read-write
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>%mutable</tt> and <tt>%immutable</tt> directives are actually
|
|
<a href="Customization.html#features">%feature directives</a> defined like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
#define %immutable %feature("immutable")
|
|
#define %mutable %feature("immutable","")
|
|
</pre></div>
|
|
|
|
<p>
|
|
If you wanted to make all wrapped variables read-only, barring one or two, it might be easier to take this approach:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%immutable; // Make all variables read-only
|
|
%feature("immutable","0") x; // except, make x read/write
|
|
...
|
|
double x;
|
|
double y;
|
|
double z;
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
Read-only variables are also created when declarations are declared as <tt>const</tt>.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
const int foo; /* Read only variable */
|
|
char * const version="1.0"; /* Read only variable */
|
|
</pre></div>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> Read-only access used to be controlled by a pair of directives
|
|
<tt>%readonly</tt> and <tt>%readwrite</tt>. Although these directives still work, they
|
|
generate a warning message. Simply change the directives to <tt>%immutable;</tt> and
|
|
<tt>%mutable;</tt> to silence the warning. Don't forget the extra semicolon!
|
|
</p>
|
|
|
|
<H3><a name="SWIG_rename_ignore"></a>5.4.7 Renaming and ignoring declarations</H3>
|
|
|
|
|
|
<p>
|
|
Normally, the name of a C declaration is used when that declaration is
|
|
wrapped into the target language. However, this may generate a
|
|
conflict with a keyword or already existing function in the scripting
|
|
language. To resolve a name conflict, you can use the <tt>%rename</tt>
|
|
directive as shown :</p>
|
|
|
|
<div class="code"><pre>
|
|
// interface.i
|
|
|
|
%rename(my_print) print;
|
|
extern void print(char *);
|
|
|
|
%rename(foo) a_really_long_and_annoying_name;
|
|
extern int a_really_long_and_annoying_name;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG still calls the correct C function, but in this case the
|
|
function <tt>print()</tt> will really be called "<tt>my_print()</tt>"
|
|
in the target language. </p>
|
|
|
|
<p>
|
|
The placement of the <tt>%rename</tt> directive is arbitrary as long as it appears
|
|
before the declarations to be renamed. A common technique is to write code for
|
|
wrapping a header file like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
// interface.i
|
|
|
|
%rename(my_print) print;
|
|
%rename(foo) a_really_long_and_annoying_name;
|
|
|
|
%include "header.h"
|
|
</pre></div>
|
|
|
|
<p>
|
|
<tt>%rename </tt>applies a renaming operation to all future
|
|
occurrences of a name. The renaming applies to functions, variables,
|
|
class and structure names, member functions, and member data. For
|
|
example, if you had two-dozen C++ classes, all with a member function
|
|
named `print' (which is a keyword in Python), you could rename them
|
|
all to `output' by specifying :</p>
|
|
|
|
<div class="code"><pre>
|
|
%rename(output) print; // Rename all `print' functions to `output'
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG does not normally perform any checks to see if the functions it wraps are
|
|
already defined in the target scripting language. However, if you are
|
|
careful about namespaces and your use of modules, you can usually
|
|
avoid these problems.</p>
|
|
|
|
<p>
|
|
Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive. <tt>%ignore</tt> instructs SWIG
|
|
to ignore declarations that match a given identifier. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%ignore print; // Ignore all declarations named print
|
|
%ignore _HAVE_FOO_H; // Ignore an include guard constant
|
|
...
|
|
%include "foo.h" // Grab a header file
|
|
...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Any function, variable etc which matches <tt>%ignore</tt> will not be wrapped and therefore will not be available from the target language.
|
|
A common usage of <tt>%ignore</tt> is to selectively remove certain declarations from a header file without having
|
|
to add conditional compilation to the header. However, it should be stressed that this only works for simple
|
|
declarations. If you need to remove a whole section of problematic code, the SWIG preprocessor should be used instead.
|
|
</p>
|
|
|
|
<p>
|
|
More powerful variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
|
|
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
|
|
<a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility note: </b> Older versions of SWIG provided a special <tt>%name</tt> directive for renaming declarations.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%name(output) extern void print(char *);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This directive is still supported, but it is deprecated and should probably be avoided. The <tt>%rename</tt>
|
|
directive is more powerful and better supports wrapping of raw header file information.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_default_args"></a>5.4.8 Default/optional arguments</H3>
|
|
|
|
|
|
<p>
|
|
SWIG supports default arguments in both C and C++ code. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
int plot(double x, double y, int color=WHITE);
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case, SWIG generates wrapper code where the
|
|
default arguments are optional in the target language. For example, this function could be
|
|
used in Tcl as follows :</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
% plot -3.4 7.5 # Use default value
|
|
% plot -3.4 7.5 10 # set color to 10 instead
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Although the ANSI C standard does not allow default arguments, default
|
|
arguments specified in a SWIG interface work with both C and C++.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Note:</b> There is a subtle semantic issue concerning the use
|
|
of default arguments and the SWIG generated wrapper code. When default
|
|
arguments are used in C code, the default values are emitted into the wrappers and the
|
|
function is invoked with a full set of arguments. This is different to when wrapping C++
|
|
where an overloaded wrapper method is generated for each defaulted argument.
|
|
Please refer to the section on <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a>
|
|
in the C++ chapter for further details.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn30"></a>5.4.9 Pointers to functions and callbacks</H3>
|
|
|
|
|
|
<p>
|
|
Occasionally, a C library may include functions that expect to receive
|
|
pointers to functions--possibly to serve as callbacks. SWIG
|
|
provides full support for function pointers provided that the callback
|
|
functions are defined in C and not in the target language. For example,
|
|
consider a function like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
int binary_op(int a, int b, int (*op)(int,int));
|
|
</pre></div>
|
|
|
|
<p>
|
|
When you first wrap something like this into an extension module, you
|
|
may find the function to be impossible to use. For instance, in Python:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
>>> def add(x,y):
|
|
... return x+y
|
|
...
|
|
>>> binary_op(3,4,add)
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: Type error. Expected _p_f_int_int__int
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The reason for this error is that SWIG doesn't know how to map a scripting
|
|
language function into a C callback. However, existing C functions can
|
|
be used as arguments provided you install them as constants.
|
|
One way to do this is to use the <tt>%constant</tt> directive like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
/* Function with a callback */
|
|
int binary_op(int a, int b, int (*op)(int,int));
|
|
|
|
/* Some callback functions */
|
|
%constant int add(int,int);
|
|
%constant int sub(int,int);
|
|
%constant int mul(int,int);
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case, <tt>add</tt>, <tt>sub</tt>, and <tt>mul</tt> become function pointer
|
|
constants in the target scripting language. This allows you to use them as follows:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> binary_op(3,4,add)
|
|
7
|
|
>>> binary_op(3,4,mul)
|
|
12
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Unfortunately, by declaring the callback functions as constants, they are no longer accessible
|
|
as functions. For example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> add(3,4)
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: object is not callable: '_ff020efc_p_f_int_int__int'
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If you want to make a function available as both a callback function and a function, you
|
|
can use the <tt>%callback</tt> and <tt>%nocallback</tt> directives like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Function with a callback */
|
|
int binary_op(int a, int b, int (*op)(int,int));
|
|
|
|
/* Some callback functions */
|
|
%callback("%s_cb");
|
|
int add(int,int);
|
|
int sub(int,int);
|
|
int mul(int,int);
|
|
%nocallback;
|
|
</pre></div>
|
|
|
|
<p>
|
|
The argument to <tt>%callback</tt> is a printf-style format string that
|
|
specifies the naming convention for the callback constants (<tt>%s</tt> gets replaced
|
|
by the function name). The callback mode remains in effect until it is explicitly
|
|
disabled using <tt>%nocallback</tt>. When you do this, the interface now works as follows:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
>>> binary_op(3,4,add_cb)
|
|
7
|
|
>>> binary_op(3,4,mul_cb)
|
|
12
|
|
>>> add(3,4)
|
|
7
|
|
>>> mul(3,4)
|
|
12
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Notice that when the function is used as a callback, special names
|
|
such as <tt>add_cb</tt> is used instead. To call the function
|
|
normally, just use the original function name such as <tt>add()</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG provides a number of extensions to standard C printf formatting
|
|
that may be useful in this context. For instance, the following
|
|
variation installs the callbacks as all upper-case constants such as
|
|
<tt>ADD</tt>, <tt>SUB</tt>, and <tt>MUL</tt>:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
/* Some callback functions */
|
|
%callback("%(upper)s");
|
|
int add(int,int);
|
|
int sub(int,int);
|
|
int mul(int,int);
|
|
%nocallback;
|
|
</pre></div>
|
|
|
|
<p>
|
|
A format string of <tt>"%(lower)s"</tt> converts all characters to lower-case.
|
|
A string of <tt>"%(title)s"</tt> capitalizes the first character and converts the
|
|
rest to lower case.
|
|
</p>
|
|
|
|
<p>
|
|
And now, a final note about function pointer support. Although SWIG
|
|
does not normally allow callback functions to be written in the target language, this
|
|
can be accomplished with the use of typemaps and other advanced SWIG features.
|
|
This is described in a later chapter.
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn31"></a>5.5 Structures and unions</H2>
|
|
|
|
|
|
<p>
|
|
This section describes the behavior of SWIG when processing ANSI C structures and union declarations. Extensions to
|
|
handle C++ are described in the next section.
|
|
</p>
|
|
|
|
<p>
|
|
If SWIG encounters the definition of a structure or union, it
|
|
creates a set of accessor functions. Although SWIG does not need
|
|
structure definitions to build an interface, providing definitions
|
|
make it possible to access structure members. The accessor functions
|
|
generated by SWIG simply take a pointer to an object and allow access
|
|
to an individual member. For example, the declaration :</p>
|
|
|
|
<div class="code"><pre>
|
|
struct Vector {
|
|
double x,y,z;
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
gets transformed into the following set of accessor functions :</p>
|
|
|
|
<div class="code"><pre>
|
|
double Vector_x_get(struct Vector *obj) {
|
|
return obj->x;
|
|
}
|
|
double Vector_y_get(struct Vector *obj) {
|
|
return obj->y;
|
|
}
|
|
double Vector_z_get(struct Vector *obj) {
|
|
return obj->z;
|
|
}
|
|
void Vector_x_set(struct Vector *obj, double value) {
|
|
obj->x = value;
|
|
}
|
|
void Vector_y_set(struct Vector *obj, double value) {
|
|
obj->y = value;
|
|
}
|
|
void Vector_z_set(struct Vector *obj, double value) {
|
|
obj->z = value;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
In addition, SWIG creates default constructor and destructor functions if none are
|
|
defined in the interface. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
struct Vector *new_Vector() {
|
|
return (Vector *) calloc(1,sizeof(struct Vector));
|
|
}
|
|
void delete_Vector(struct Vector *obj) {
|
|
free(obj);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Using these low-level accessor functions, an object can be minimally manipulated from the target
|
|
language using code like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
v = new_Vector()
|
|
Vector_x_set(v,2)
|
|
Vector_y_set(v,10)
|
|
Vector_z_set(v,-5)
|
|
...
|
|
delete_Vector(v)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
However, most of SWIG's language modules also provide a high-level interface that is more convenient. Keep reading.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn32"></a>5.5.1 Typedef and structures</H3>
|
|
|
|
|
|
<p>
|
|
SWIG supports the following construct which is quite common in C
|
|
programs :</p>
|
|
|
|
<div class="code"><pre>
|
|
typedef struct {
|
|
double x,y,z;
|
|
} Vector;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
When encountered, SWIG assumes that the name of the object is `Vector'
|
|
and creates accessor functions like before. The only difference is
|
|
that the use of <tt>typedef</tt> allows SWIG to drop the
|
|
<tt>struct</tt> keyword on its generated code. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
double Vector_x_get(Vector *obj) {
|
|
return obj->x;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If two different names are used like this :</p>
|
|
|
|
<div class="code"><pre>
|
|
typedef struct vector_struct {
|
|
double x,y,z;
|
|
} Vector;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
the name <tt>Vector</tt> is used instead of <tt>vector_struct</tt> since
|
|
this is more typical C programming style. If declarations defined later in the interface use the type <tt>struct
|
|
vector_struct</tt>, SWIG knows that this is the same as
|
|
<tt>Vector</tt> and it generates the appropriate type-checking code.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn33"></a>5.5.2 Character strings and structures</H3>
|
|
|
|
|
|
<p>
|
|
Structures involving character strings require some care. SWIG assumes
|
|
that all members of type <tt>char *</tt> have been dynamically
|
|
allocated using <tt>malloc()</tt> and that they are NULL-terminated
|
|
ASCII strings. When such a member is modified, the previously contents
|
|
will be released, and the new contents allocated. For example :</p>
|
|
|
|
<div class="code"><pre>
|
|
%module mymodule
|
|
...
|
|
struct Foo {
|
|
char *name;
|
|
...
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
This results in the following accessor functions :</p>
|
|
|
|
<div class="code"><pre>
|
|
char *Foo_name_get(Foo *obj) {
|
|
return Foo->name;
|
|
}
|
|
|
|
char *Foo_name_set(Foo *obj, char *c) {
|
|
if (obj->name) free(obj->name);
|
|
obj->name = (char *) malloc(strlen(c)+1);
|
|
strcpy(obj->name,c);
|
|
return obj->name;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
If this behavior differs from what you need in your applications,
|
|
the SWIG "memberin" typemap can be used to change it. See the
|
|
typemaps chapter for further details.
|
|
</p>
|
|
|
|
<p>
|
|
Note: If the <tt>-c++</tt> option is used, <tt>new</tt> and <tt>delete</tt> are used to
|
|
perform memory allocation.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn34"></a>5.5.3 Array members</H3>
|
|
|
|
|
|
<p>
|
|
Arrays may appear as the members of structures, but they will be
|
|
read-only. SWIG will write an accessor function that returns the
|
|
pointer to the first element of the array, but will not write a
|
|
function to change the contents of the array itself.
|
|
When this
|
|
situation is detected, SWIG may generate a warning message such as the
|
|
following :</p>
|
|
|
|
<div class="shell"><pre>
|
|
interface.i:116. Warning. Array member will be read-only
|
|
</pre></div>
|
|
|
|
<p>
|
|
To eliminate the warning message, typemaps can be used, but this is
|
|
discussed in a later chapter. In many cases, the warning message is
|
|
harmless.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_structure_data_members"></a>5.5.4 Structure data members</H3>
|
|
|
|
|
|
<p>
|
|
Occasionally, a structure will contain data members that are themselves structures. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
typedef struct Foo {
|
|
int x;
|
|
} Foo;
|
|
|
|
typedef struct Bar {
|
|
int y;
|
|
Foo f; /* struct member */
|
|
} Bar;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When a structure member is wrapped, it is handled as a pointer, unless the <tt>%naturalvar</tt> directive
|
|
is used where it is handled more like a C++ reference (see <a href="SWIGPlus.html#SWIGPlus_member_data">C++ Member data</a>).
|
|
The accessors to the member variable as a pointer is effectively wrapped as follows:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Foo *Bar_f_get(Bar *b) {
|
|
return &b->f;
|
|
}
|
|
void Bar_f_set(Bar *b, Foo *value) {
|
|
b->f = *value;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The reasons for this are somewhat subtle but have to do with the
|
|
problem of modifying and accessing data inside the data member. For
|
|
example, suppose you wanted to modify the value of <tt>f.x</tt>
|
|
of a <tt>Bar</tt> object like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Bar *b;
|
|
b->f.x = 37;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Translating this assignment to function calls (as would be used inside the scripting
|
|
language interface) results in the following code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Bar *b;
|
|
Foo_x_set(Bar_f_get(b),37);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this code, if the <tt>Bar_f_get()</tt> function were to return a <tt>Foo</tt> instead of a
|
|
<tt>Foo *</tt>, then the resulting modification would be applied to a <em>copy</em> of <tt>f</tt> and not
|
|
the data member <tt>f</tt> itself. Clearly that's not what you want!
|
|
</p>
|
|
|
|
<p>
|
|
It should be noted that this transformation to pointers only occurs if SWIG knows that a data member
|
|
is a structure or class. For instance, if you had a structure like this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Foo {
|
|
WORD w;
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
and nothing was known about <tt>WORD</tt>, then SWIG will generate more normal accessor functions
|
|
like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
WORD Foo_w_get(Foo *f) {
|
|
return f->w;
|
|
}
|
|
void Foo_w_set(FOO *f, WORD value) {
|
|
f->w = value;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>Compatibility Note: </b> SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes
|
|
to pointers. Starting in SWIG-1.3.12, this transformation <em>only</em> occurs if a datatype is known to be a structure,
|
|
class, or union. This is unlikely to break existing code. However, if you need to tell SWIG that an undeclared
|
|
datatype is really a struct, simply use a forward struct declaration such as <tt>"struct Foo;"</tt>.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn36"></a>5.5.5 C constructors and destructors </H3>
|
|
|
|
|
|
<p>
|
|
When wrapping structures, it is generally useful to have a mechanism
|
|
for creating and destroying objects. If you don't do anything, SWIG
|
|
will automatically generate functions for creating and destroying
|
|
objects using <tt>malloc()</tt> and <tt>free()</tt>. Note: the use of
|
|
<tt>malloc()</tt> only applies when SWIG is used on C code (i.e., when the
|
|
<tt>-c++</tt> option is <em>not</em> supplied on the command line). C++ is handled
|
|
differently.
|
|
</p>
|
|
|
|
<p>
|
|
If you don't want SWIG to generate default constructors for your
|
|
interfaces, you can use the <tt>%nodefaultctor</tt> directive or the
|
|
<tt>-nodefaultctor</tt> command line option. For example:
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
swig -nodefaultctor example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
or
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module foo
|
|
...
|
|
%nodefaultctor; // Don't create default constructors
|
|
... declarations ...
|
|
%clearnodefaultctor; // Re-enable default constructors
|
|
</pre></div>
|
|
|
|
<p>
|
|
If you need more precise control, <tt>%nodefaultctor</tt> can selectively target individual structure
|
|
definitions. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%nodefaultctor Foo; // No default constructor for Foo
|
|
...
|
|
struct Foo { // No default constructor generated.
|
|
};
|
|
|
|
struct Bar { // Default constructor generated.
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
Since ignoring the implicit or default destructors most of the times
|
|
produce memory leaks, SWIG will always try to generate them. If
|
|
needed, however, you can selectively disable the generation of the
|
|
default/implicit destructor by using <tt>%nodefaultdtor </tt>
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%nodefaultdtor Foo; // No default/implicit destructor for Foo
|
|
...
|
|
struct Foo { // No default destructor is generated.
|
|
};
|
|
|
|
struct Bar { // Default destructor generated.
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> Prior to SWIG-1.3.7, SWIG did not generate default constructors
|
|
or destructors unless you explicitly turned them on using <tt>-make_default</tt>.
|
|
However, it appears that most users want to have constructor and destructor functions so it
|
|
has now been enabled as the default behavior.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Note:</b> There are also the <tt>-nodefault</tt> option and
|
|
<tt>%nodefault</tt> directive, which disable both the default or
|
|
implicit destructor generation. This could lead to memory leaks across
|
|
the target languages, and is highly recommended you don't use them.
|
|
</p>
|
|
|
|
|
|
<H3><a name="SWIG_adding_member_functions"></a>5.5.6 Adding member functions to C structures</H3>
|
|
|
|
|
|
<p>
|
|
Most languages provide a mechanism for creating classes and
|
|
supporting object oriented programming. From a C standpoint, object
|
|
oriented programming really just boils down to the process of
|
|
attaching functions to structures. These functions normally operate
|
|
on an instance of the structure (or object). Although there is a
|
|
natural mapping of C++ to such a scheme, there is no direct mechanism
|
|
for utilizing it with C code. However, SWIG provides a special
|
|
<tt>%extend</tt> directive that makes it possible to attach
|
|
methods to C structures for purposes of building an object oriented
|
|
interface. Suppose you have a C header file with
|
|
the following declaration :</p>
|
|
|
|
<div class="code"><pre>
|
|
/* file : vector.h */
|
|
...
|
|
typedef struct {
|
|
double x,y,z;
|
|
} Vector;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interface like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
// file : vector.i
|
|
%module mymodule
|
|
%{
|
|
#include "vector.h"
|
|
%}
|
|
|
|
%include vector.h // Just grab original C header file
|
|
%extend Vector { // Attach these functions to struct Vector
|
|
Vector(double x, double y, double z) {
|
|
Vector *v;
|
|
v = (Vector *) malloc(sizeof(Vector));
|
|
v->x = x;
|
|
v->y = y;
|
|
v->z = z;
|
|
return v;
|
|
}
|
|
~Vector() {
|
|
free($self);
|
|
}
|
|
double magnitude() {
|
|
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
|
|
}
|
|
void print() {
|
|
printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z);
|
|
}
|
|
};
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Note the usage of the <tt>$self</tt> special variable.
|
|
Its usage is identical to a C++ 'this' pointer and should be used whenever access to the struct instance is required.
|
|
</p>
|
|
|
|
<p>
|
|
Now, when used with proxy classes in Python, you can do things like
|
|
this :</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
>>> v = Vector(3,4,0) # Create a new vector
|
|
>>> print v.magnitude() # Print magnitude
|
|
5.0
|
|
>>> v.print() # Print it out
|
|
[ 3, 4, 0 ]
|
|
>>> del v # Destroy it
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>%extend</tt> directive can also be used inside the definition
|
|
of the Vector structure. For example:</p>
|
|
|
|
<div class="code"><pre>
|
|
// file : vector.i
|
|
%module mymodule
|
|
%{
|
|
#include "vector.h"
|
|
%}
|
|
|
|
typedef struct {
|
|
double x,y,z;
|
|
%extend {
|
|
Vector(double x, double y, double z) { ... }
|
|
~Vector() { ... }
|
|
...
|
|
}
|
|
} Vector;
|
|
</pre></div>
|
|
|
|
<p>
|
|
Finally, <tt>%extend</tt> can be used to access externally written
|
|
functions provided they follow the naming convention used in this
|
|
example :</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : vector.c */
|
|
/* Vector methods */
|
|
#include "vector.h"
|
|
Vector *new_Vector(double x, double y, double z) {
|
|
Vector *v;
|
|
v = (Vector *) malloc(sizeof(Vector));
|
|
v->x = x;
|
|
v->y = y;
|
|
v->z = z;
|
|
return v;
|
|
}
|
|
void delete_Vector(Vector *v) {
|
|
free(v);
|
|
}
|
|
|
|
double Vector_magnitude(Vector *v) {
|
|
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
|
}
|
|
|
|
// File : vector.i
|
|
// Interface file
|
|
%module mymodule
|
|
%{
|
|
#include "vector.h"
|
|
%}
|
|
|
|
typedef struct {
|
|
double x,y,z;
|
|
%extend {
|
|
Vector(int,int,int); // This calls new_Vector()
|
|
~Vector(); // This calls delete_Vector()
|
|
double magnitude(); // This will call Vector_magnitude()
|
|
...
|
|
}
|
|
} Vector;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
A little known feature of the <tt>%extend</tt> directive is that
|
|
it can also be used to add synthesized attributes or to modify the
|
|
behavior of existing data attributes. For example, suppose you wanted
|
|
to make <tt>magnitude</tt> a read-only attribute of <tt>Vector</tt>
|
|
instead of a method. To do this, you might write some code like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// Add a new attribute to Vector
|
|
%extend Vector {
|
|
const double magnitude;
|
|
}
|
|
// Now supply the implementation of the Vector_magnitude_get function
|
|
%{
|
|
const double Vector_magnitude_get(Vector *v) {
|
|
return (const double) return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
|
}
|
|
%}
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Now, for all practical purposes, <tt>magnitude</tt> will appear like an attribute
|
|
of the object.
|
|
</p>
|
|
|
|
<p>
|
|
A similar technique can also be used to work with problematic data members.
|
|
For example, consider this interface:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Person {
|
|
char name[50];
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
By default, the <tt>name</tt> attribute is read-only because SWIG does not
|
|
normally know how to modify arrays. However, you can rewrite the interface
|
|
as follows to change this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Person {
|
|
%extend {
|
|
char *name;
|
|
}
|
|
...
|
|
}
|
|
|
|
// Specific implementation of set/get functions
|
|
%{
|
|
char *Person_name_get(Person *p) {
|
|
return p->name;
|
|
}
|
|
void Person_name_set(Person *p, char *val) {
|
|
strncpy(p->name,val,50);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Finally, it should be stressed that even though <tt>%extend</tt>
|
|
can be used to add new data members, these new members can not require
|
|
the allocation of additional storage in the object (e.g., their values must
|
|
be entirely synthesized from existing attributes of the structure).
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> The <tt>%extend</tt> directive is a new
|
|
name for the <tt>%addmethods</tt> directive. Since <tt>%addmethods</tt> could
|
|
be used to extend a structure with more than just methods, a more suitable
|
|
directive name has been chosen.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nested_structs"></a>5.5.7 Nested structures</H3>
|
|
|
|
|
|
<p>
|
|
Occasionally, a C program will involve structures like this :</p>
|
|
|
|
<div class="code"><pre>
|
|
typedef struct Object {
|
|
int objtype;
|
|
union {
|
|
int ivalue;
|
|
double dvalue;
|
|
char *strvalue;
|
|
void *ptrvalue;
|
|
} intRep;
|
|
} Object;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
When SWIG encounters this, it performs a structure splitting operation
|
|
that transforms the declaration into the equivalent of the
|
|
following:</p>
|
|
|
|
<div class="code"><pre>
|
|
typedef union {
|
|
int ivalue;
|
|
double dvalue;
|
|
char *strvalue;
|
|
void *ptrvalue;
|
|
} Object_intRep;
|
|
|
|
typedef struct Object {
|
|
int objType;
|
|
Object_intRep intRep;
|
|
} Object;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG will then create an <tt>Object_intRep</tt> structure for use inside
|
|
the interface file. Accessor functions will be created for both
|
|
structures. In this case, functions like this would be created :</p>
|
|
|
|
<div class="code"><pre>
|
|
Object_intRep *Object_intRep_get(Object *o) {
|
|
return (Object_intRep *) &o->intRep;
|
|
}
|
|
int Object_intRep_ivalue_get(Object_intRep *o) {
|
|
return o->ivalue;
|
|
}
|
|
int Object_intRep_ivalue_set(Object_intRep *o, int value) {
|
|
return (o->ivalue = value);
|
|
}
|
|
double Object_intRep_dvalue_get(Object_intRep *o) {
|
|
return o->dvalue;
|
|
}
|
|
... etc ...
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Although this process is a little hairy, it works like you would expect in the
|
|
target scripting language--especially when proxy classes are used. For instance, in Perl:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Perl5 script for accessing nested member
|
|
$o = CreateObject(); # Create an object somehow
|
|
$o->{intRep}->{ivalue} = 7 # Change value of o.intRep.ivalue
|
|
</pre></div>
|
|
|
|
<p>
|
|
If you have a lot nested structure declarations, it is
|
|
advisable to double-check them after running SWIG. Although,
|
|
there is a good chance that they will work, you may have to
|
|
modify the interface file in certain cases.
|
|
|
|
<H3><a name="SWIG_nn39"></a>5.5.8 Other things to note about structure wrapping</H3>
|
|
|
|
|
|
<p>
|
|
SWIG doesn't care if the declaration of a structure in a <tt>.i</tt> file exactly matches
|
|
that used in the underlying C code (except in the case of nested
|
|
structures). For this reason, there are no problems omitting
|
|
problematic members or simply omitting the structure definition
|
|
altogether. If you are happy passing pointers around, this can
|
|
be done without ever giving SWIG a structure definition.</p>
|
|
|
|
<p>
|
|
Starting with SWIG1.3, a number of improvements have been made to SWIG's
|
|
code generator. Specifically, even though structure access has been described
|
|
in terms of high-level accessor functions such as this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
double Vector_x_get(Vector *v) {
|
|
return v->x;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
most of the generated code is actually inlined directly into wrapper
|
|
functions. Therefore, no function <tt>Vector_x_get()</tt> actually
|
|
exists in the generated wrapper file. For example, when creating a Tcl module,
|
|
the following function is generated instead:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
static int
|
|
_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp,
|
|
int objc, Tcl_Obj *CONST objv[]) {
|
|
struct Vector *arg1 ;
|
|
double result ;
|
|
|
|
if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0,
|
|
SWIGTYPE_p_Vector) == TCL_ERROR)
|
|
return TCL_ERROR;
|
|
result = (double ) (arg1->x);
|
|
Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));
|
|
return TCL_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The only exception to this rule are methods defined with <tt>%extend</tt>. In this
|
|
case, the added code is contained in a separate function.
|
|
</p>
|
|
|
|
<p>
|
|
Finally, it is important to note that most language modules may choose to
|
|
build a more advanced interface. Although you may never use the low-level
|
|
interface described here, most of SWIG's language modules use it in
|
|
some way or another.
|
|
</p>
|
|
|
|
<H2><a name="SWIG_nn40"></a>5.6 Code Insertion</H2>
|
|
|
|
|
|
<p>
|
|
Sometimes it is necessary to insert special code into the resulting
|
|
wrapper file generated by SWIG. For example, you may want to include
|
|
additional C code to perform initialization or other operations.
|
|
There are four common ways to insert code, but it's useful to know how the
|
|
output of SWIG is structured first.</p>
|
|
|
|
<H3><a name="SWIG_nn41"></a>5.6.1 The output of SWIG</H3>
|
|
|
|
|
|
<p>
|
|
When SWIG creates its output file, it is broken up into four sections
|
|
corresponding to runtime code, headers, wrapper functions, and module
|
|
initialization code (in that order).
|
|
</p>
|
|
|
|
<ul>
|
|
<li><b>Runtime code</b>. <br>
|
|
This code is internal to SWIG and is used to include
|
|
type-checking and other support functions that are used by the rest of the module.
|
|
</li>
|
|
|
|
<li><b>Header section</b>. <br>
|
|
This is user-defined support code that has been included by
|
|
the <tt>%{ ... %}</tt> directive. Usually this consists of header files and
|
|
other helper functions.
|
|
</li>
|
|
|
|
<li><b>Wrapper code</b>. <br>
|
|
These are the wrappers generated automatically by SWIG.
|
|
</li>
|
|
|
|
<li><b>Module initialization</b>. <br>
|
|
The function generated by SWIG to initialize
|
|
the module upon loading.
|
|
</li>
|
|
</ul>
|
|
|
|
<H3><a name="SWIG_nn42"></a>5.6.2 Code insertion blocks</H3>
|
|
|
|
|
|
<p>
|
|
Code is inserted into the appropriate code section by using one
|
|
of the following code insertion directives:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%runtime %{
|
|
... code in runtime section ...
|
|
%}
|
|
|
|
%header %{
|
|
... code in header section ...
|
|
%}
|
|
|
|
%wrapper %{
|
|
... code in wrapper section ...
|
|
%}
|
|
|
|
%init %{
|
|
... code in init section ...
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The bare <tt>%{ ... %}</tt> directive is a shortcut that is the same as
|
|
<tt>%header %{ ... %}</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
Everything in a code insertion block is copied verbatim into the output file and is
|
|
not parsed by SWIG. Most SWIG input files have at least one such block to include header
|
|
files and support C code. Additional code blocks may be placed anywhere in a
|
|
SWIG file as needed. </p>
|
|
|
|
<div class="code"><pre>
|
|
%module mymodule
|
|
%{
|
|
#include "my_header.h"
|
|
%}
|
|
... Declare functions here
|
|
%{
|
|
|
|
void some_extra_function() {
|
|
...
|
|
}
|
|
%}
|
|
</pre></div>
|
|
|
|
<p>
|
|
A common use for code blocks is to write "helper" functions. These
|
|
are functions that are used specifically for the purpose of building
|
|
an interface, but which are generally not visible to the normal C
|
|
program. For example :</p>
|
|
|
|
<div class="code"><pre>
|
|
%{
|
|
/* Create a new vector */
|
|
static Vector *new_Vector() {
|
|
return (Vector *) malloc(sizeof(Vector));
|
|
}
|
|
|
|
%}
|
|
// Now wrap it
|
|
Vector *new_Vector();
|
|
</pre></div>
|
|
|
|
<H3><a name="SWIG_nn43"></a>5.6.3 Inlined code blocks</H3>
|
|
|
|
|
|
<p>
|
|
Since the process of writing helper functions is fairly common,
|
|
there is a special inlined form of code block that is used as follows
|
|
:</p>
|
|
|
|
<div class="code"><pre>
|
|
%inline %{
|
|
/* Create a new vector */
|
|
Vector *new_Vector() {
|
|
return (Vector *) malloc(sizeof(Vector));
|
|
}
|
|
%}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>%inline</tt> directive inserts all of the code that follows
|
|
verbatim into the header portion of an interface file. The code is
|
|
then parsed by both the SWIG preprocessor and parser.
|
|
Thus, the above example creates a new command <tt>new_Vector</tt> using only one
|
|
declaration. Since the code inside an <tt>%inline %{ ... %}</tt> block
|
|
is given to both the C compiler and SWIG, it is illegal to include any
|
|
SWIG directives inside a <tt>%{ ... %}</tt> block.</p>
|
|
|
|
<H3><a name="SWIG_nn44"></a>5.6.4 Initialization blocks</H3>
|
|
|
|
|
|
<p>
|
|
When code is included in the <tt>%init</tt> section, it is copied directly into the
|
|
module initialization function. For example, if you needed to perform some extra
|
|
initialization on module loading, you could write this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%init %{
|
|
init_variables();
|
|
%}
|
|
</pre></div>
|
|
|
|
<H2><a name="SWIG_nn45"></a>5.7 An Interface Building Strategy</H2>
|
|
|
|
|
|
<p>
|
|
This section describes the general approach for building interface
|
|
with SWIG. The specifics related to a particular scripting language
|
|
are found in later chapters.</p>
|
|
|
|
<H3><a name="SWIG_nn46"></a>5.7.1 Preparing a C program for SWIG</H3>
|
|
|
|
|
|
<p>
|
|
SWIG doesn't require modifications to your C code, but if you feed it
|
|
a collection of raw C header files or source code, the results might
|
|
not be what you expect---in fact, they might be awful. Here's a series
|
|
of steps you can follow to make an interface for a C program :</p>
|
|
|
|
<ul>
|
|
<li>Identify the functions that you want to wrap. It's probably not
|
|
necessary to access every single function in a C program--thus, a
|
|
little forethought can dramatically simplify the resulting scripting
|
|
language interface. C header files are particularly good source for
|
|
finding things to wrap.
|
|
|
|
<li>Create a new interface file to describe the scripting language
|
|
interface to your program.
|
|
|
|
<li>Copy the appropriate declarations into the interface file or use
|
|
SWIG's <tt>%include</tt> directive to process an entire C
|
|
source/header file.
|
|
|
|
<li>Make sure everything in the interface file uses ANSI C/C++syntax.
|
|
|
|
<li>Make sure all necessary `<tt>typedef</tt>' declarations and
|
|
type-information is available in the interface file.
|
|
|
|
<li>If your program has a main() function, you may need to rename it
|
|
(read on).
|
|
|
|
<li>Run SWIG and compile.
|
|
</ul>
|
|
|
|
<p>
|
|
Although this may sound complicated, the process turns out to be
|
|
fairly easy once you get the hang of it.
|
|
</p>
|
|
|
|
<p>
|
|
In the process of building an interface, SWIG may encounter syntax errors or
|
|
other problems. The best way to deal with this is to simply copy the offending
|
|
code into a separate interface file and edit it. However, the SWIG developers
|
|
have worked very hard to improve the SWIG parser--you should report parsing errors
|
|
to the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or to the
|
|
<a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>.
|
|
</p>
|
|
|
|
<H3><a name="SWIG_nn47"></a>5.7.2 The SWIG interface file</H3>
|
|
|
|
|
|
<p>
|
|
The preferred method of using SWIG is to generate separate interface
|
|
file. Suppose you have the following C header file :</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : header.h */
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
extern int foo(double);
|
|
extern double bar(int, int);
|
|
extern void dump(FILE *f);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
A typical SWIG interface file for this header file would look like the
|
|
following :</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : interface.i */
|
|
%module mymodule
|
|
%{
|
|
#include "header.h"
|
|
%}
|
|
extern int foo(double);
|
|
extern double bar(int, int);
|
|
extern void dump(FILE *f);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Of course, in this case, our header file is pretty simple so we could
|
|
have made an interface file like this as well:</p>
|
|
|
|
<div class="code"><pre>
|
|
/* File : interface.i */
|
|
%module mymodule
|
|
%include header.h
|
|
</pre></div>
|
|
|
|
<p>
|
|
Naturally, your mileage may vary.</p>
|
|
|
|
<H3><a name="SWIG_nn48"></a>5.7.3 Why use separate interface files?</H3>
|
|
|
|
|
|
<p>
|
|
Although SWIG can parse many header files, it is more common to write a
|
|
special <tt>.i</tt> file defining the interface to a package. There
|
|
are several reasons why you might want to do this:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>It is rarely necessary to access every single function in a large
|
|
package. Many C functions might have little or no use in a scripted
|
|
environment. Therefore, why wrap them?
|
|
|
|
<li>Separate interface files provide an opportunity to provide more
|
|
precise rules about how an interface is to be constructed.
|
|
|
|
<li>Interface files can provide more structure and organization.
|
|
|
|
<li>SWIG can't parse certain definitions that appear in header
|
|
files. Having a separate file allows you to eliminate or work around
|
|
these problems.
|
|
|
|
<li>Interface files provide a more precise definition of what the interface
|
|
is. Users wanting to extend the system can go to the interface file
|
|
and immediately see what is available without having to dig it out of
|
|
header files.
|
|
</ul>
|
|
|
|
<H3><a name="SWIG_nn49"></a>5.7.4 Getting the right header files</H3>
|
|
|
|
|
|
<p>
|
|
Sometimes, it is necessary to use certain header files in order for
|
|
the code generated by SWIG to compile properly. Make sure you
|
|
include certain header files by using a <tt>%{,%}</tt> block like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module graphics
|
|
%{
|
|
#include <GL/gl.h>
|
|
#include <GL/glu.h>
|
|
%}
|
|
|
|
// Put rest of declarations here
|
|
...
|
|
</pre></div>
|
|
|
|
<H3><a name="SWIG_nn50"></a>5.7.5 What to do with main()</H3>
|
|
|
|
|
|
<p>
|
|
If your program defines a <tt>main()</tt> function, you may need to
|
|
get rid of it or rename it in order to use a scripting language. Most
|
|
scripting languages define their own <tt>main()</tt> procedure that
|
|
is called instead. <tt>main()</tt> also makes no sense when
|
|
working with dynamic loading. There are a few approaches to solving
|
|
the <tt>main()</tt> conflict :</p>
|
|
|
|
<ul>
|
|
<li>Get rid of <tt>main()</tt> entirely.
|
|
|
|
<li>Rename <tt>main()</tt> to something else. You can do this by
|
|
compiling your C program with an option like <tt>-Dmain=oldmain</tt>.
|
|
|
|
<li>Use conditional compilation to only include <tt>main()</tt> when
|
|
not using a scripting language.
|
|
</ul>
|
|
|
|
<p>
|
|
Getting rid of <tt>main()</tt> may cause potential initialization
|
|
problems of a program. To handle this problem, you may consider
|
|
writing a special function called <tt>program_init()</tt> that
|
|
initializes your program upon startup. This function could then be
|
|
called either from the scripting language as the first operation, or
|
|
when the SWIG generated module is loaded.</p>
|
|
|
|
<p>
|
|
As a general note, many C programs only use the <tt>main()</tt>
|
|
function to parse command line options and to set parameters. However,
|
|
by using a scripting language, you are probably trying to create a
|
|
program that is more interactive. In many cases, the old
|
|
<tt>main()</tt> program can be completely replaced by a Perl, Python,
|
|
or Tcl script.</p>
|
|
|
|
<p>
|
|
<b>Note:</b> If some cases, you might be inclined to create a
|
|
scripting language wrapper for <tt>main()</tt>. If you do this, the
|
|
compilation will probably work and your module might even load
|
|
correctly. The only trouble is that when you call your
|
|
<tt>main()</tt> wrapper, you will find that it actually invokes the
|
|
<tt>main()</tt> of the scripting language interpreter itself! This behavior
|
|
is a side effect of the symbol binding mechanism used in the dynamic linker.
|
|
The bottom line: don't do this.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|