git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
959 lines
29 KiB
HTML
959 lines
29 KiB
HTML
<html>
|
|
<head>
|
|
<title>SWIG Internals</title>
|
|
</head>
|
|
|
|
<body>
|
|
<center>
|
|
<h1>SWIG Internals Manual</h1>
|
|
|
|
<b>Thien-Thi Nguyen <br>
|
|
ttn@glug.org <br>
|
|
|
|
<p>
|
|
David M. Beazley <br>
|
|
beazley@cs.uchicago.edu </br>
|
|
|
|
</b>
|
|
</center>
|
|
|
|
<p>
|
|
<b>$Header$</b>
|
|
|
|
<p>
|
|
(Note : This is a work in progress.)
|
|
|
|
<h2>Table of Contents</h2>
|
|
<ul>
|
|
<li><a name="i1" href="#1">1. Introduction</a>
|
|
<ul>
|
|
<li><a name="i1.1" href="#1.1">1.1 Directory Guide</a>
|
|
<li><a name="i1.2" href="#1.2">1.2 Overall Program Flow</a>
|
|
</ul>
|
|
<li><a name="i2" href="#2">2. DOH</a>
|
|
<ul>
|
|
<li><a name="i2.1" href="#2.1">2.1 Motivation and Background</a>
|
|
<li><a name="i2.2" href="#2.2">2.2 Basic Types</a>
|
|
<li><a name="i2.3" href="#2.3">2.3 Creating, Copying and Destroying Objects</a>
|
|
<li><a name="i2.4" href="#2.4">2.4 A Word About Mutability and Copying</a>
|
|
<li><a name="i2.5" href="#2.5">2.5 Strings</a>
|
|
<li><a name="i2.6" href="#2.6">2.6 Lists</a>
|
|
<li><a name="i2.7" href="#2.7">2.7 Hash Tables</a>
|
|
<li><a name="i2.8" href="#2.8">2.8 Files</a>
|
|
<li><a name="i2.9" href="#2.9">2.9 Void Objects</a>
|
|
<li><a name="i2.10" href="#2.10">2.10 Utility Functions</a>
|
|
</ul>
|
|
<li><a name="i3" href="#3">3. Types and Typemaps</a>
|
|
<li><a name="i4" href="#4">4. Parsing</a>
|
|
<li><a name="i5" href="#5">5. Difference Between SWIG 1.1 and SWIG 1.3</a>
|
|
<li><a name="i6" href="#6">6. Plans for SWIG 2.0</a>
|
|
<li><a name="i7" href="#7">7. C/C++ Wrapper Support Functions</a>
|
|
<li><a name="i8" href="#8">8. Reserved</a>
|
|
<li><a name="i9" href="#9">9. Reserved</a>
|
|
<li><a name="i10" href="#10">10. Guile Support</a>
|
|
<li><a name="i11" href="#11">11. Python Support</a>
|
|
<li><a name="i12" href="#12">12. Perl Support</a>
|
|
<li><a name="i13" href="#13">13. Java Support</a>
|
|
</ul>
|
|
|
|
<a name="1" href="#i1">
|
|
<h2>1. Introduction</h2>
|
|
</a>
|
|
|
|
This document details SWIG internals: architecture and sometimes
|
|
implementation. The first few sections concentrate on data structures,
|
|
interfaces, conventions and code shared by all language targets.
|
|
Subsequent sections focus on a particular language.
|
|
|
|
<p>
|
|
The audience is assumed to be SWIG developers (who should also read the
|
|
<a href="engineering.html">SWIG Engineering Manual</a> before starting
|
|
to code).
|
|
|
|
<a name="1.1" href="#i1.1">
|
|
<h3>1.1 Directory Guide</h3>
|
|
</a>
|
|
|
|
<table border=1>
|
|
<tr><td><a href="index.html">Doc</a></td>
|
|
<td>HTML documentation. If you find a documentation bug, please
|
|
<a href="mailto:bug-swig-doc@glug.org">let us know</a>.</td>
|
|
</tr>
|
|
|
|
<tr><td>Examples</td>
|
|
<td>This subdir tree contains examples of using SWIG w/ different
|
|
scripting languages, including makefiles. Typically, there are the
|
|
"simple" and "matrix" examples, w/ some languages offering additional
|
|
examples. The GIFPlot example has its own set of per-language
|
|
subdirectories. See the README more index.html file in each directory
|
|
for more info. [FIXME: Ref SWIG user manual.]</td>
|
|
</tr>
|
|
|
|
<tr><td>Lib</td>
|
|
<td>These are the <tt>.i</tt> (interface) files that form the SWIG
|
|
installed library. Language-specific files are in subdirectories (for
|
|
example, guile/typemaps.i). Each language also has a <tt>.swg</tt> file
|
|
implementing runtime type support for that language. The SWIG library
|
|
is not versioned.</td>
|
|
</tr>
|
|
|
|
<tr><td>Misc</td>
|
|
<td>Currently this subdir only contains file <tt>fileheader</tt>. See
|
|
the <a href="engineering.html">Engineering Manual</a> for more
|
|
info.</td>
|
|
</tr>
|
|
|
|
<tr><td>Runtime</td>
|
|
<td>This subdir contains scripts and a makefile for creating runtime
|
|
shared-object libraries used by various languages. Runtime/make.sh
|
|
says: "The runtime libraries are only needed if you are building
|
|
multiple extension modules that need to share information."</td>
|
|
</tr>
|
|
|
|
<tr><td>Source</td>
|
|
<td>SWIG source code is in this subdir tree. Directories marked w/ "(*)"
|
|
are used in building the <tt>swig</tt> executable.
|
|
|
|
<table border=1>
|
|
|
|
<tr><td>DOH (*)</td>
|
|
<td>C library providing memory allocation, file access and generic
|
|
containers. Result: libdoh.a</td>
|
|
</tr>
|
|
|
|
<tr><td>Experiment</td>
|
|
<td>[TODO]</td>
|
|
</tr>
|
|
|
|
<tr><td>Include (*)</td>
|
|
<td>Configuration .h files</td>
|
|
</tr>
|
|
|
|
<tr><td>LParse</td>
|
|
<td>Parser (lex / yacc) files and support [why not (*)?!]</td>
|
|
</tr>
|
|
|
|
<tr><td>Modules</td>
|
|
<td>[TODO]</td>
|
|
</tr>
|
|
|
|
<tr><td>Modules1.1 (*)</td>
|
|
<td>Language-specific callbacks that does actual code generation (each
|
|
language has a .cxx and a .h file). Result: libmodules11.a</td>
|
|
</tr>
|
|
|
|
<tr><td>Preprocessor (*)</td>
|
|
<td>SWIG-specialized C/C++ preprocessor. Result: libcpp.a</td>
|
|
</tr>
|
|
|
|
<tr><td>SWIG1.1 (*)</td>
|
|
<td>Parts of SWIG that are not language-specific, including option
|
|
processing and the type-mapping system. Result: libswig11.a.
|
|
Note: This directory is currently being phased out. </td>
|
|
</tr>
|
|
|
|
<tr><td>SWIG1.3</td>
|
|
<td>[TODO] [funny, nothing here is presently used for swig-1.3].
|
|
This directory might turn into a compatibility interface between
|
|
SWIG1.3 and the SWIG1.1 modules.</td>
|
|
</tr>
|
|
|
|
<tr><td>Swig (*)</td>
|
|
<td>This directory contains the new ANSI C core of the system
|
|
and contains generic functions related to types, file handling,
|
|
scanning, and so forth.</td>
|
|
</tr>
|
|
|
|
</table></td>
|
|
</tr>
|
|
|
|
<tr><td>Tools</td>
|
|
<td>Libtool support and the mkdist.py script.</td>
|
|
</tr>
|
|
|
|
<tr><td>Win</td>
|
|
<td>This improperly-named (spit spit) subdir only has README.txt.</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
|
|
<a name="1.2" href="#1.2">
|
|
<h3>1.2 Overall Program Flow</h3>
|
|
</a>
|
|
|
|
Here is the general control flow and where under subdir <tt>Source</tt>
|
|
to look for code:
|
|
|
|
<ul>
|
|
|
|
<li> <tt>Modules1.1/swigmain.cxx:main()</tt> is the program entry
|
|
point. It parses the language-specifying command-line option (for
|
|
example, <tt>-java</tt>), creating a new language-specific wrapping
|
|
object (each language is a C++ class derived from base class
|
|
<tt>Language</tt>). This object and the command-line is passed to
|
|
<tt>SWIG_main()</tt>, whose return value is the program exit value.
|
|
|
|
<li> <tt>SWIG1.1/main.cxx:SWIG_main()</tt> is the "real" main. It
|
|
initializes the preprocessor and typemap machinery, defines some
|
|
preprocessor symbols, locates the SWIG library, processes common
|
|
command-line options, and then calls the language-specific command-line
|
|
parser. From here there are three paths: "help", "checkout" and
|
|
everything else.
|
|
<ul>
|
|
<li> In "help" mode, clean up open files and exit.
|
|
<li> In "checkout" mode, copy specified files from the SWIG library
|
|
to the current directory. Errors cause error messages but no
|
|
non-lcoal exits.
|
|
<li> Otherwise, do wrapping: determine output file name(s), define
|
|
some preprocessor symbols and run the preprocessor, initialize
|
|
the interface-definition parser, set up the typemap for handling
|
|
new return strings, and finally do the language-specific parse
|
|
(by calling the language object's <tt>parse()</tt> method), which
|
|
creates output files by side-effect.
|
|
</ul>
|
|
Afterwards, remove temporary files, and clean up. If the command-line
|
|
included <tt>-freeze</tt>, go into an infinite loop; otherwise return the
|
|
error count.
|
|
|
|
<li> The language-specific <tt>parse()</tt> (and all other
|
|
language-specific code) lives in <tt>Modules1.1/foo.{h,cxx}</tt> for
|
|
language Foo. Typically, <tt>FOO::parse()</tt> calls
|
|
<tt>FOO::headers()</tt> and then the global function <tt>yyparse()</tt>,
|
|
which uses the callbacks registered by <tt>SWIG_main()</tt> above.
|
|
|
|
</ul>
|
|
|
|
<a name="2" href="#i2">
|
|
<h2>2. DOH</h2>
|
|
</a>
|
|
|
|
DOH is a collection of low-level objects such as strings, lists, and
|
|
hash tables upon which the rest of SWIG is built. The name 'DOH'
|
|
unofficially stands for "Dave's Object Hack", but it's also a good
|
|
expletive to use when things don't work (as in "SWIG core
|
|
dumped---DOH!").
|
|
|
|
<a name="2.1" href="#2.1">
|
|
<h3>2.1 Motivation and Background</h3>
|
|
</a>
|
|
|
|
The development of DOH is influenced heavily by the problems
|
|
encountered during earlier attempts to create a C++ based version of
|
|
SWIG2.0. In each of these attempts (over a 3 year period), the
|
|
resulting system always ended up growing into a collossal nightmare of
|
|
large inheritance hierarchies and dozens of specialized classes for
|
|
different types of objects (functions, variables, constants, etc.).
|
|
The end result was that the system was tremendously complicated,
|
|
difficult to understand, difficult to maintain, and fairly inflexible
|
|
in the grand scheme of things.
|
|
|
|
<p>
|
|
DOH takes a different approach to tackling the complexity problem.
|
|
First, rather than going overboard with dozens of types and class
|
|
definitions, DOH only defines a handful of simple yet very useful
|
|
objects that are easy to remember. Second, DOH uses dynamic
|
|
typing---one of the features that make scripting languages so useful
|
|
and which make it possible to accomplish things with much less code.
|
|
Finally, DOH utilizes a few coding tricks that allow it to perform
|
|
a limited form of function overloading for certain C datatypes (more
|
|
on that a little later).
|
|
|
|
<p>
|
|
The key point to using DOH is that instead of thinking about code in
|
|
terms of highly specialized C data structures, just about everything
|
|
ends up being represented in terms of a just a few datatypes. For
|
|
example, structures are replaced by DOH hash tables whereas arrays are
|
|
replaced by DOH lists. At first, this is probably a little strange to
|
|
most C/C++ programmers, but in the long run in makes the system
|
|
extremely flexible and highly extensible. Also, in terms of coding,
|
|
many of the newly DOH-based subsystems are less than half the size (in
|
|
lines of code) of the earlier C++ implementation.
|
|
|
|
<a name="2.2" href="#i2.2">
|
|
<h3>2.2 Basic Types</h3>
|
|
</a>
|
|
|
|
The following built-in types are currently provided by DOH:
|
|
|
|
<ul>
|
|
<li><b>String</b>. A string of characters with automatic memory
|
|
management and high-level operations such as string replacement. In addition,
|
|
strings support file I/O operations that make it possible to use them just
|
|
about anyplace a file can be used.
|
|
|
|
<p>
|
|
<li><b>List</b>. A list of arbitrary DOH objects (of possibly mixed types).
|
|
|
|
<p>
|
|
<li><b>Hash</b>. A hash table that maps a set of string keys to a set of arbitrary
|
|
DOH objects. The DOH version of an associative array for all of you Perl fans.
|
|
|
|
<p>
|
|
<li><b>File</b>. A DOH wrapper around the C FILE * structure. This is provided
|
|
since other objects sometimes want to behave like files (strings for instance).
|
|
|
|
<p>
|
|
<li><b>Void</b>. A DOH wrapper around an arbitrary C pointer. This can be used
|
|
if you want to place arbitrary C data structures in DOH lists and hash tables.
|
|
</ul>
|
|
|
|
Due to dynamic typing, all of the objects in DOH are represented by pointers
|
|
of type <tt>DOH *</tt>. Furthermore, all objects are completely
|
|
opaque--that means that the only way to access the internals of an
|
|
object is through a well-defined public API. For convenience, the following
|
|
symbolic names are sometimes used to improve readability:
|
|
|
|
<ul>
|
|
<Li><tt>DOHString *</tt>. A String object.
|
|
<li><tt>DOHList *</tt>. A list object.
|
|
<li><tt>DOHHash *</tt>. A hash object.
|
|
<li><tt>DOHFile *</tt>. A file object.
|
|
<li><tt>DOHVoid *</tt>. A void object.
|
|
<li><tt>DOHString_or_char *</tt>. A DOH String object or a raw C "char *".
|
|
</ul>
|
|
|
|
It should be stressed that all of these names are merely symbolic aliases to the
|
|
type <tt>DOH *</tt> and that no compile-time type checking is performed (of course,
|
|
a runtime error may occur if you screw up).
|
|
|
|
<a name="2.3" href="#i2.3">
|
|
<h3>2.3 Creating, Copying, and Destroying Objects </h2>
|
|
</a>
|
|
|
|
The following functions can be used to create new DOH objects
|
|
|
|
<ul>
|
|
<Li><tt>NewString(DOHString_or_char *value)</tt><br>
|
|
Create a new string object with contents initially
|
|
set to value. value can be either a C string or a DOH string object.
|
|
|
|
<p>
|
|
<li><tt>NewStringf(char *fmt, ...)</tt><br>
|
|
Create a new string object with contents initially set to
|
|
a formatted string. Think of this as being sprintf() combined with an object constructor.
|
|
|
|
<p>
|
|
<li><tt>NewList()</tt><br>
|
|
Create a new list object that is initially empty.
|
|
|
|
<p>
|
|
<Li><tt>NewHash()</tt><br>
|
|
Create a new hash object that is initially empty.
|
|
|
|
<p>
|
|
<li><tt>NewFile(DOHString_or_char *filename, char *mode)</tt><br>
|
|
Open a file and return a file object. This is a
|
|
wrapper around the C <tt>fopen()</tt> library call.
|
|
|
|
<p>
|
|
<li><tt>NewFileFromFile(FILE *f)</tt><br>
|
|
Create a new file object given an already opened <tt>FILE *</tt> object.
|
|
|
|
<p>
|
|
<li><tt>NewVoid(void *obj, void (*del)(void *))</tt><br>
|
|
Create a new DOH object that is a wrapper around an
|
|
arbitrary C pointer. <tt>del</tt> is an optional destructor function that will be called when the object
|
|
is destroyed.
|
|
|
|
</ul>
|
|
|
|
Any object can be copied using the <tt>Copy()</tt> function. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
DOH *a, *b, *c, *d;
|
|
a = NewString("Hello World");
|
|
b = NewList();
|
|
c = Copy(a); /* Copy the string a */
|
|
d = Copy(b); /* Copy the list b */
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Copies of lists and hash tables are shallow. That is, their contents are only copied by reference.
|
|
|
|
<p>
|
|
Objects can be deleted using the <tt>Delete()</tt> function. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
DOH *a = NewString("Hello World");
|
|
...
|
|
Delete(a); /* Destroy a */
|
|
</pre>
|
|
</blockquote>
|
|
|
|
All objects are referenced counted and given a reference count of 1 when initially created. The
|
|
<tt>Delete()</tt> function only destroys an object when the reference count reaches zero. When
|
|
an object is placed in a list or hash table, it's reference count is automatically increased. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
DOH *a, *b;
|
|
a = NewString("Hello World");
|
|
b = NewList();
|
|
Append(b,a); /* Increases refcnt of a to 2 */
|
|
Delete(a); /* Decreases refcnt of a to 1 */
|
|
Delete(b); /* Destroys b, and destroys a */
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Should it ever be necessary to manually increase the reference count of an object, the DohIncref() function
|
|
can be used:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
DOH *a = NewString("Hello");
|
|
DohIncref(a);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="2.4" href="#i2.4">
|
|
<h3>2.4 A Word About Mutability and Copying</h3>
|
|
</a>
|
|
|
|
All DOH objects are mutable regardless of their current reference
|
|
count. For example, if you create a string and then create a 1000
|
|
references to it (in lists and hash tables), changes to the string
|
|
will be reflected in all of the references. Therefore, if you need to
|
|
make any kind of local change, you should first make a copy using the
|
|
Copy() function. Caveat: when copying lists and hash tables, elements
|
|
are copied by reference.
|
|
|
|
<a name="2.5" href="#i2.5">
|
|
<h3>2.5 Strings</h3>
|
|
</a>
|
|
|
|
The DOH String type is perhaps the most flexible object. First, it supports a variety of string-oriented
|
|
operations. Second, it supports many of the same operations as lists. Finally, strings provide file I/O
|
|
operations that allow them to be used interchangably with DOH file objects.
|
|
|
|
[ TODO ]
|
|
|
|
<a name="2.6" href="#i2.6">
|
|
<h3>2.6 Lists</h3>
|
|
</a>
|
|
|
|
[ TODO ]
|
|
|
|
<a name="2.7" href="#i2.7">
|
|
<h3>2.7 Hash tables </h3>
|
|
</a>
|
|
|
|
[ TODO ]
|
|
|
|
<a name="2.8" href="#i2.8">
|
|
<h3>2.8 Files </h3>
|
|
</a>
|
|
|
|
[ TODO ]
|
|
|
|
<a name="2.9" href="#i2.9">
|
|
<h3>2.9 Void objects </h3>
|
|
</a>
|
|
|
|
[ TODO ]
|
|
|
|
<a name="2.10" href="#i2.10">
|
|
<h3>2.10 Utility functions </h3>
|
|
</a>
|
|
|
|
[ TODO ]
|
|
|
|
<a name="3" href="#i3">
|
|
<h2>3. Types and Typemaps</h2>
|
|
</a>
|
|
|
|
Revised: Dave Beazley (8/14/00)
|
|
|
|
<p>
|
|
The representation and manipulation of types is currently in the
|
|
process of being reorganized and (hopefully) simplified. The
|
|
following list describes the current set of functions that are used to
|
|
manipulate datatypes. These functions are different than in
|
|
SWIG1.1 and may change names in the final SWIG1.3 release.
|
|
|
|
<ul>
|
|
<li><tt>SwigType_str(SwigType *t, char *name)</tt>.<br>
|
|
This function produces the exact string
|
|
representation of the datatype <tt>t</tt>. <tt>name</tt> is an optional parameter that
|
|
specifies a declaration name. This is used when dealing with more complicated datatypes
|
|
such as arrays and pointers to functions where the output might look something like
|
|
"<tt>int (*name)(int, double)</tt>".
|
|
|
|
<p>
|
|
<li><tt>SwigType_lstr(SwigType *t, char *name)</tt>.<br>
|
|
This function produces a string
|
|
representation of a datatype that can be safely be assigned a value (i.e., can be used as the
|
|
"lvalue" of an expression). To do this, qualifiers such as "const", arrays, and references
|
|
are stripped away or converted into pointers. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Original Datatype lstr()
|
|
------------------ --------
|
|
const char *a char *a
|
|
double a[20] double *a
|
|
double a[20][30] double *a
|
|
double &a double *a
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The intent of the lstr() function is to produce local variables inside wrapper functions--all
|
|
of which must be reassignable types since they are the targets of conversions from a scripting
|
|
representation.
|
|
|
|
<p>
|
|
<li><tt>SwigType_rcaststr(SwigType *t, char *name)</tt>.
|
|
<br> This function produces a string
|
|
that casts a type produced by the <tt>lstr()</tt> function to the type produced by the
|
|
<tt>str()</tt> function. You might view it as the inverse of lstr(). This function only produces
|
|
output when it needs to (when str() and lstr() produce different results). Furthermore, an optional
|
|
name can be supplied when the cast is to be applied to a specific name. Examples:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Original Datatype rcaststr()
|
|
------------------ ---------
|
|
char *a
|
|
const char *a (const char *) name
|
|
double a[20] (double *) name
|
|
double a[20][30] (double (*)[30]) name
|
|
double &a (double &) *name
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<p>
|
|
<li><tt>SwigType_lcaststr(SwigType *t, char *name)</tt>.
|
|
<br> This function produces a string
|
|
that casts a type produced by the <tt>str()</tt> function to the type produced by the
|
|
<tt>lstr()</tt> function. This function only produces
|
|
output when it needs to (when str() and lstr() produce different results). Furthermore, an optional
|
|
name can be supplied when the cast is to be applied to a specific name.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Original Datatype lcaststr()
|
|
------------------ ---------
|
|
char *a
|
|
const char *a (char *) name
|
|
double a[20] (double *) name
|
|
double a[20][30] (double *) name
|
|
double &a (double *) &name
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
<li><tt>SwigType_manglestr(SwigType *t)</tt>. <br>
|
|
Produces a type-string that is used to identify this datatype in the target scripting language.
|
|
Usually this string looks something like "<tt>_p_p_double</tt>" although the target language
|
|
may redefine the output for its own purposes. Normally this function strips all qualifiers,
|
|
references, and arrays---producing a mangled version of the type produced by the <tt>lstr()</tt> function.
|
|
</ul>
|
|
|
|
The following example illustrates the intended use of the above functions when creating wrapper
|
|
functions using shorthand pseudocode. Suppose you had a function like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
int foo(int a, double b[20][30], const char *c, double &d);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Here's how a wrapper function would be generated using the type generation functions above:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
wrapper_foo() {
|
|
lstr("int","result")
|
|
lstr("int","arg0")
|
|
lstr("double [20][30]", "arg1")
|
|
lstr("const char *", "arg2")
|
|
lstr("double &", "arg3")
|
|
...
|
|
get arguments
|
|
...
|
|
result = (lcaststr("int")) foo(rcaststr("int","arg0"),
|
|
rcaststr("double [20][30]","arg1"),
|
|
rcaststr("const char *", "arg2"),
|
|
rcaststr("double &", "arg3"))
|
|
...
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Here's how it would look with the corresponding output filled in:
|
|
<blockquote>
|
|
<pre>
|
|
wrapper_foo() {
|
|
int result;
|
|
int arg0;
|
|
double *arg1;
|
|
char *arg2;
|
|
double *arg3;
|
|
...
|
|
get arguments
|
|
...
|
|
result = (int) foo(arg0,
|
|
(double (*)[30]) arg1,
|
|
(const char *) arg2,
|
|
(double &) *arg3);
|
|
...
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<b>Notes:</b>
|
|
|
|
<ul>
|
|
<li>For convenience, the string generation functions return a
|
|
"<tt>char *</tt>" that points to statically allocated memory living
|
|
inside the type library. Therefore, it is never necessary (and it's
|
|
an error) to free the pointer returned by the functions. Also, if you
|
|
need to save the result, you should make a copy of it. However, with
|
|
that said, it is probably worth nothing that these functions do cache
|
|
the last 8 results. Therefore, it's fairly safe to make a handful of
|
|
repeated calls without making any copies.
|
|
</ul>
|
|
|
|
[TODO]
|
|
|
|
<a name="4" href="#i4">
|
|
<h2>4. Parsing</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<a name="5" href="#i5">
|
|
<h2>5. Difference Between SWIG 1.1 and SWIG 1.3</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<a name="6" href="#i6">
|
|
<h2>6. Plans for SWIG 2.0</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<a name="7" href="#i7">
|
|
<h2>7. The C/C++ Wrapping Layer</h2>
|
|
</a>
|
|
|
|
Added: Dave Beazley (July 22, 2000)
|
|
|
|
<p>
|
|
When SWIG generates wrappers, it tries to provide a mostly seamless integration
|
|
with the original code. However, there are a number of problematic features
|
|
of C/C++ programs that complicate this interface.
|
|
|
|
<ul>
|
|
<li><b>Passing and returning structures by value.</b> When used, SWIG converts
|
|
all pass-by-value functions into wrappers that pass by reference. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
double dot_product(Vector a, Vector b);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
gets turned into a wrapper like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
double wrap_dot_product(Vector *a, Vector *b) {
|
|
return dot_product(*a,*b);
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Functions that return by value require a memory allocation to store the result. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Vector cross_product(Vector *a, Vector *b);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
become
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Vector *wrap_cross_product(Vector *a, Vector *b) {
|
|
Vector *result = (Vector *) malloc(sizeof(Vector));
|
|
*result = cross_product(a,b);
|
|
return result;
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Note: If C++ is being wrapped, the default copy constructor is used
|
|
instead of malloc() to create a copy of the return result.
|
|
|
|
<p>
|
|
<li><b>C++ references</b>. C++ references are handled exactly the same as
|
|
pass/return by value except that a memory allocation is not made for functions
|
|
that return a reference.
|
|
|
|
<p>
|
|
<li><b>Qualifiers such as "const" and "volatile".</b> SWIG strips all
|
|
qualifiers from the interface presented to the target language.
|
|
Besides, what in the heck is "const" in Perl anyways?
|
|
|
|
<p>
|
|
<li><b>Instance Methods</b>. Method invocations are handled as a function call in which
|
|
a pointer to the object (the "this" pointer) appears as the first argument. For example, in
|
|
the following class:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
class Foo {
|
|
public:
|
|
double bar(double);
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The "bar" method is wrapped by a function like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
double Foo_bar(Foo *self, double arg0) {
|
|
return self->bar(arg0);
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
<li><b>Structure/class data members</b>. Data members are handled by creating a pair
|
|
of wrapper functions that set and get the value respectively. For example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
struct Foo {
|
|
int x;
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
gets wrapped as follows:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
int Foo_x_get(Foo *self) {
|
|
return self->x;
|
|
}
|
|
int Foo_x_set(Foo *self, int value) {
|
|
return (self->x = value);
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
<li><b>Constructors</b>. Constructors for C/C++ data structures are wrapped by
|
|
a function like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
Foo *new_Foo() {
|
|
return new Foo;
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
Note: For C, new objects are created using the calloc() function.
|
|
|
|
<p>
|
|
<li><b>Destructors</b>. Destructors for C/C++ data structures are wrapper like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
void delete_Foo(Foo *self) {
|
|
delete self;
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
Note: For C, objects are destroyed using free().
|
|
|
|
</ul>
|
|
|
|
The creation of wrappers and various type transformations are handled by a collection of functions
|
|
found in the file <tt>Source/Swig/cwrap.c</tt>.
|
|
|
|
<ul>
|
|
<li>
|
|
<tt>char *Swig_clocal(DataType *t, char *name, char *value)</tt><br>
|
|
This function creates a string containing the declaration of a local variable with
|
|
type <tt>t</tt>, name <tt>name</tt>, and default value <tt>value</tt>. This local
|
|
variable is stripped of all qualifiers and will be a pointer if the type is a reference
|
|
or user defined type.
|
|
|
|
<p>
|
|
<li>
|
|
<tt>DataType *Swig_clocal_type(DataType *t)</tt><br>
|
|
Returns a type object corresponding to the type string produced by the Swig_clocal() function.
|
|
|
|
<p>
|
|
<li><tt>char *Swig_clocal_deref(DataType *t, char *name)</tt><br>
|
|
This function is the inverse of the <tt>clocal()</tt> function. Given a type and a name,
|
|
it produces a string containing the code needed to cast/convert the type produced by
|
|
<tt>Swig_clocal()</tt> back into it's original type.
|
|
|
|
<p>
|
|
<li><tt>char *Swig_clocal_assign(DataType *t, char *name)</tt><br>
|
|
Given a type and name, this produces a string containing the code (and an optional cast)
|
|
needed to make an assignment from the real datatype to the local datatype produced
|
|
by <tt>Swig_clocal()</tt>. Kind of the opposite of deref().
|
|
|
|
<p>
|
|
<li><tt>int Swig_cargs(Wrapper *w, ParmList *l)</tt><br>
|
|
Given a wrapper function object and a list of parameters, this function declares a set
|
|
of local variables for holding all of the parameter values (using Swig_clocal()). Returns
|
|
the number of parameters. In addition, this function sets the local name of each parameter
|
|
which can be retrieved using the <tt>Parm_Getlname()</tt> function.
|
|
|
|
<p>
|
|
<li><tt>void Swig_cresult(Wrapper *w, DataType *t, char *resultname, char *decl)</tt><br>
|
|
Generates the code needed to set the result of a wrapper function and performs all of
|
|
the needed memory allocations for ANSI C (if necessary). <tt>t</tt> is the type of the
|
|
result, <tt>resultname</tt> is the name of the result variable, and <tt>decl</tt> is
|
|
a string that contains the C code which produces the result.
|
|
|
|
<p>
|
|
<li><tt>void Swig_cppresult(Wrapper *w, DataType *t, char *resultname, char *decl)</tt><br>
|
|
Generates the code needed to set the result of a wrapper function and performs all of
|
|
the needed memory allocations for C++ (if necessary). <tt>t</tt> is the type of the
|
|
result, <tt>resultname</tt> is the name of the result variable, and <tt>decl</tt> is
|
|
a string that contains the C code which produces the result.
|
|
|
|
<p>
|
|
<li><tt>Wrapper *Swig_cfunction_wrapper(char *fname, DataType *rtype, ParmList *parms, char *code)</tt><br>
|
|
Create a wrapper around a normal function declaration. <tt>fname</tt> is the name of the wrapper,
|
|
<tt>rtype</tt> is the return type, <tt>parms</tt> are the function parameters, and <tt>code</tt> is a
|
|
string containing the code in the function body.
|
|
|
|
<p>
|
|
<li><tt>Wrapper *Swig_cmethod_wrapper(char *classname, char *methodname, DataType *rtype, DataType *parms, char *code)</tt><br>
|
|
|
|
<p>
|
|
<li><tt>char *Swig_cfunction_call(char *name, ParmList *parms)</tt>
|
|
This function produces a string containing the code needed to call a C function.
|
|
The string that is produced contains all of the transformations needed to convert
|
|
pass-by-value into pass-by-reference as well as handle C++ references. Produces
|
|
a string like "name(arg0, arg1, ..., argn)".
|
|
|
|
</ul>
|
|
|
|
Here is a short example showing how these functions could be used. Suppose you had a
|
|
C function like this:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
double dot_product(Vector a, Vector b);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Here's how you might write a really simple wrapper function
|
|
|
|
<blockquote>
|
|
<pre>
|
|
ParmList *l = ... parameter list of the function ...
|
|
DataType *t = ... return type of the function ...
|
|
char *name = ... name of the function ...
|
|
Wrapper *w = NewWrapper();
|
|
Printf(w->def,"void wrap_%s() {\n", name);
|
|
|
|
/* Declare all of the local variables */
|
|
Swig_cargs(w, l);
|
|
|
|
/* Convert all of the arguments */
|
|
...
|
|
|
|
/* Make the function call and declare the result variable */
|
|
Swig_cresult(w,t,"result",Swig_cfunction(name,l));
|
|
|
|
/* Convert the result into whatever */
|
|
...
|
|
|
|
Printf(w->code,"}\n");
|
|
Wrapper_print(w,out);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The output of this would appear as follows:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
void wrap_dot_product() {
|
|
Vector *arg0;
|
|
Vector *arg1;
|
|
double result;
|
|
|
|
...
|
|
result = dot_product(*arg0, *arg1);
|
|
...
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Notice that the <tt>Swig_cargs()</tt>, <tt>Swig_cresult()</tt>, and <tt>Swig_cfunction()</tt> functions
|
|
have taken care of the type conversions for the <tt>Vector</tt> type automatically.
|
|
|
|
<p>
|
|
<b>Notes:</b>
|
|
<ul>
|
|
<Li>The intent of these functions is to provide <em>consistent</em> handling of function parameters
|
|
and return values so that language module writers don't have to worry about it too much.
|
|
|
|
<p>
|
|
<li>These functions may be superceded by features in the new typemap system which provide hooks
|
|
for specifying local variable declarations and argument conversions.
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="8" href="#i8">
|
|
<h2>8. Reserved</h2>
|
|
</a>
|
|
|
|
<a name="9" href="#i9">
|
|
<h2>9. Reserved</h2>
|
|
</a>
|
|
|
|
<a name="10" href="#i10">
|
|
<h2>10. Guile Support</h2>
|
|
</a>
|
|
|
|
The information that used to live here has moved to the user
|
|
documentation, file <code>Guile.html</code>.
|
|
|
|
<a name="11" href="#i11">
|
|
<h2>11. Python Support</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<a name="12" href="#i12">
|
|
<h2>12. Perl Support</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<a name="13" href="#i13">
|
|
<h2>13. Java Support</h2>
|
|
</a>
|
|
|
|
[TODO]
|
|
|
|
<hr>
|
|
Copyright (C) 1999-2001
|
|
<a href="mailto:swig-dev@cs.uchicago.edu">SWIG Development Team</a>
|
|
|
|
</body>
|
|
</html>
|