git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5411 626c5289-ae23-0410-ae9c-e8d60b6d4f22
533 lines
No EOL
17 KiB
HTML
533 lines
No EOL
17 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<!-- Hand-written HTML -->
|
|
<html>
|
|
<head>
|
|
<title>SWIG and Chicken</title>
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
|
|
<a name="n1"></a><H1>24 SWIG and Chicken</H1>
|
|
<!-- INDEX -->
|
|
<ul>
|
|
<li><a href="#n2">Preliminaries</a>
|
|
<ul>
|
|
<li><a href="#n3">Running SWIG in C mode</a>
|
|
<li><a href="#n4">Running SWIG in C++ mode</a>
|
|
</ul>
|
|
<li><a href="#n5">Code Generation</a>
|
|
<ul>
|
|
<li><a href="#n6">Naming Conventions</a>
|
|
<li><a href="#n7">Modules and Prefixes</a>
|
|
<li><a href="#n8">Constants and Variables</a>
|
|
<li><a href="#n9">Functions</a>
|
|
</ul>
|
|
<li><a href="#n10">TinyCLOS</a>
|
|
<li><a href="#n11">Compilation</a>
|
|
<li><a href="#n12">Linkage</a>
|
|
<ul>
|
|
<li><a href="#n13">Customized Interpreter</a>
|
|
</ul>
|
|
<li><a href="#n14">Typemaps</a>
|
|
<li><a href="#n15">Pointers</a>
|
|
<li><a href="#n16">Unsupported features</a>
|
|
</ul>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
This chapter describes SWIG's support of CHICKEN. CHICKEN is a
|
|
Scheme-to-C compiler supporting most of the language features as
|
|
defined in the <i>Revised^5 Report on Scheme</i>. Its main
|
|
attributes are that it
|
|
<ol>
|
|
<li>generates portable C code</li>
|
|
<li>includes a customizable interpreter</li>
|
|
<li>links to C libraries with a simple Foreign Function Interface</li>
|
|
<li>supports full tail-recursion and first-class continuations</li>
|
|
</ol>
|
|
|
|
When confronted with a large C library, CHICKEN users can use
|
|
SWIG to generate CHICKEN wrappers for the C library. However,
|
|
the real advantages of using SWIG with CHICKEN are its
|
|
<strong>support for C++</strong> -- object-oriented code is
|
|
difficult to wrap by hand in CHICKEN -- and its <strong>typed
|
|
pointer representation</strong>, essential for C and C++
|
|
libraries involving structures or classes.
|
|
|
|
</p>
|
|
|
|
<a name="n2"></a><H2>24.1 Preliminaries</H2>
|
|
|
|
|
|
<p>
|
|
CHICKEN support was introduced to SWIG in version 1.3.18. SWIG
|
|
relies on some recent additions to CHICKEN, which are only
|
|
present in releases of CHICKEN with version number
|
|
<strong>greater than or equal to <tt>1.0</tt></strong>.
|
|
|
|
<br></br> CHICKEN can be downloaded from <a
|
|
href="http://www.call-with-current-continuation.org/chicken.html">http://www.call-with-current-continuation.org/chicken.html</a>
|
|
|
|
You may want to look at any of the examples in Examples/chicken/
|
|
or Examples/GIFPlot/Chicken for the basic steps to run SWIG
|
|
CHICKEN.
|
|
|
|
We will generically refer to the <em>wrapper</em> as the
|
|
generated files.
|
|
|
|
</p>
|
|
|
|
<a name="n3"></a><H3>24.1.1 Running SWIG in C mode</H3>
|
|
|
|
|
|
<p>
|
|
To run SWIG CHICKEN in C mode, use
|
|
the -chicken option.
|
|
<blockquote>
|
|
<pre>% swig -chicken example.i</pre>
|
|
</blockquote>
|
|
To allow the wrapper to take advantage of future CHICKEN code
|
|
generation improvements, part of the wrapper is direct CHICKEN
|
|
function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
|
|
Scheme (<tt>example.scm</tt>). The basic Scheme code must
|
|
be compiled to C using your system's CHICKEN compiler.
|
|
<blockquote>
|
|
<pre>% chicken example.scm -output-file oexample.c</pre>
|
|
</blockquote>
|
|
So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
|
|
<tt>oexample.c</tt> are the files that must be compiled to
|
|
object files and linked into your project.
|
|
</p>
|
|
|
|
<a name="n4"></a><H3>24.1.2 Running SWIG in C++ mode</H3>
|
|
|
|
|
|
<p>
|
|
To run SWIG CHICKEN in C++ mode, use
|
|
the -chicken -c++ option.
|
|
<blockquote>
|
|
<pre>% swig -chicken -c++ example.i</pre>
|
|
</blockquote>
|
|
This will generate <tt>example_wrap.cxx</tt>,
|
|
<tt>example.scm</tt>, <tt>example-generic.scm</tt> and
|
|
<tt>example-clos.scm</tt>. The basic Scheme code must be
|
|
compiled to C using your system's CHICKEN compiler.
|
|
<blockquote>
|
|
<pre>% chicken example.scm -output-file oexample.c</pre>
|
|
</blockquote>
|
|
So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
|
|
and <tt>oexample.c</tt> are the files that must be compiled to
|
|
object files and linked into your project.
|
|
|
|
</p>
|
|
|
|
<a name="n5"></a><H2>24.2 Code Generation</H2>
|
|
|
|
|
|
<a name="n6"></a><H3>24.2.1 Naming Conventions</H3>
|
|
|
|
|
|
<p>
|
|
Given a C variable, function or constant declaration named
|
|
<tt>Foo_Bar_to_Foo_Baz</tt>, the declaration will be available
|
|
in CHICKEN as an identifier ending with
|
|
<tt>foo-bar->foo-baz</tt>. That is, an underscore is converted
|
|
to a dash, '_to_' is converted to an arro, and all characters
|
|
are sent to lowercase.
|
|
|
|
<br></br>
|
|
|
|
Additionally, there is a <em>mixed</em> mode that can be
|
|
specified with the <tt>-mixed</tt> option on the SWIG command
|
|
line. In this mode, the above rules apply with the addition
|
|
that changes in case are indications to SWIG CHICKEN to place a
|
|
dash in the CHICKEN identifier. For example, a C declartaion
|
|
named <tt>someDeclaration_xyz</tt> will be available as the
|
|
CHICKEN identifier ending with <tt>some-declaration-xyz</tt>.
|
|
|
|
<br></br>
|
|
|
|
You may control what the CHICKEN identifier will be by using the
|
|
<tt>%rename</tt> SWIG directive in the SWIG interface file.
|
|
</p>
|
|
|
|
<a name="n7"></a><H3>24.2.2 Modules and Prefixes</H3>
|
|
|
|
|
|
<p>
|
|
SWIG CHICKEN does not use the standard CHICKEN module system
|
|
(which has been deprecated); instead, it uses a prefix system.
|
|
Specifying the module name as 'example' in SWIG CHICKEN can be
|
|
done using either of:
|
|
<ul>
|
|
<li>Placing <tt>%module example</tt> in the SWIG interface
|
|
file.</li>
|
|
<li>Using <tt>-module example</tt> on the SWIG command
|
|
line.</li>
|
|
</ul>
|
|
|
|
CHICKEN will be able to access the module using the <tt>(declare
|
|
(uses <i>modulename</i>))</tt> CHICKEN Scheme form.
|
|
|
|
<br></br>
|
|
|
|
Normally, for a C declaration <tt>Foo_Bar</tt> with a module
|
|
name of 'example', the corresponding CHICKEN identifier will be
|
|
<tt>example:foo-bar</tt>. <strong>The module name and a colon is
|
|
prefixed to the CHICKEN identifier</strong> (following normal
|
|
naming conventions).
|
|
|
|
<br></br>
|
|
|
|
You may explicitly override the prefix with the SWIG command
|
|
line option <tt>-prefix <i>whateverprefix</i></tt>, or you may
|
|
remove the prefix with the option <tt>-noprefix</tt>.
|
|
|
|
</p>
|
|
|
|
<a name="n8"></a><H3>24.2.3 Constants and Variables</H3>
|
|
|
|
|
|
<p>
|
|
Constants may be created using any of the four constructs in
|
|
the interface file:
|
|
<ol>
|
|
<li><code>#define MYCONSTANT1 ...</code></li>
|
|
<li><code>%constant int MYCONSTANT2 = ...</code></li>
|
|
<li><code>const int MYCONSTANT3 = ...</code></li>
|
|
<li><code>enum { MYCONSTANT4 = ... };</code></li>
|
|
</ol>
|
|
|
|
In all cases, the constants may be accessed from with CHICKEN
|
|
using the form <tt>(myconstant1)</tt>; that is, the constants
|
|
may be accessed using the read-only parameter form.
|
|
</p>
|
|
|
|
<p>
|
|
Variables are accessed using the full parameter form.
|
|
For example, to set the C variable "int my_variable;", use the
|
|
Scheme form <tt>(my-variable 2345)</tt>. To get the C variable,
|
|
use <tt>(my-variable)</tt>.
|
|
</p>
|
|
|
|
<a name="n9"></a><H3>24.2.4 Functions</H3>
|
|
|
|
|
|
<p>
|
|
C functions declared in the SWIG interface file will have
|
|
corresponding CHICKEN Scheme procedures. For example, the C
|
|
function "int sqrt(double x);" will be available using the
|
|
Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return
|
|
value will give C_SCHEME_UNDEFINED as a result.
|
|
</p>
|
|
<p>
|
|
A function may return more than one value by using the
|
|
<code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i).
|
|
They will be returned as a Scheme list if there is more than one
|
|
result (that is, a non-void return value and at least one argout
|
|
parameter, or a void return value and at least two argout
|
|
parameters).
|
|
</p>
|
|
|
|
<a name="n10"></a><H2>24.3 TinyCLOS</H2>
|
|
|
|
|
|
<p>
|
|
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
|
|
<blockquote>
|
|
Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
|
|
metaobject protocol. The implementation is even simpler than
|
|
the simple CLOS found in `The Art of the Metaobject Protocol,'
|
|
weighing in at around 850 lines of code, including (some)
|
|
comments and documentation.
|
|
</blockquote>
|
|
Almost all good Scheme books describe how to use metaobjects and
|
|
generic procedures to implement an object-oriented Scheme
|
|
system. Please consult a Scheme book if you are unfamiliar
|
|
with the concept.
|
|
|
|
<br></br>
|
|
|
|
CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
|
|
uses in C++ mode. SWIG CHICKEN generates a
|
|
<tt>xxx-generic.scm</tt> and a <tt>xxx-clos.scm</tt> file, which
|
|
contain TinyCLOS macros. When using these macros, you will need
|
|
to <tt>(include "xxx-generic")</tt> all the generic macros your
|
|
program needs, and <strong>then</strong> <tt>(include
|
|
"xxx-clos")</tt> all the metaobject (class) macros your program
|
|
needs.
|
|
|
|
<br></br>
|
|
|
|
SWIG CHICKEN will call the destructor for all TinyCLOS objects
|
|
that are garbage-collected by CHICKEN. It also allows access to
|
|
the underlying low-level Scheme procedures with (de)-marshaling
|
|
of any TinyCLOS parameters. It is best to learn the TinyCLOS
|
|
system by running the <tt>Examples/chicken/class/</tt> example.
|
|
|
|
</p>
|
|
|
|
<a name="n11"></a><H2>24.4 Compilation</H2>
|
|
|
|
|
|
<p>
|
|
Please refer to <em>CHICKEN - A practical and portable Scheme
|
|
system - User's manual</em> for detailed help on how to compile
|
|
C code for use in a CHICKEN program. Briefly, to compile C
|
|
code, be sure to add <tt>`chicken-config -cflags`</tt> or
|
|
<tt>`chicken-config -shared -cflags`</tt> to your compiler
|
|
options. Use the <tt>-shared</tt> option if you want to create
|
|
a dynamically loadable module. You might also want to use the
|
|
much simpler <tt>csc</tt> or <tt>csc.bat</tt>.
|
|
</p>
|
|
|
|
<a name="n12"></a><H2>24.5 Linkage</H2>
|
|
|
|
|
|
<p>
|
|
Please refer to <em>CHICKEN - A practical and portable Scheme
|
|
system - User's manual</em> for detailed help on how to link
|
|
object files to create a CHICKEN Scheme program. Briefly, to
|
|
link object files, be sure to add <tt>`chicken-config
|
|
-extra-libs -libs`</tt> or <tt>`chicken-config -shared
|
|
-extra-libs -libs`</tt>to your linker options. Use the
|
|
<tt>-shared</tt> option if you want to create a dynamically
|
|
loadable module.
|
|
</p>
|
|
<p>
|
|
All the following examples assume that the module is named
|
|
'example' and the following occurs when run:
|
|
<blockquote>
|
|
<pre>% chicken-config -home
|
|
CHICKEN_HOME=/usr/local/share/chicken</pre>
|
|
</blockquote>
|
|
Substitute <tt>/usr/local/share/chicken</tt> as appropriate for
|
|
your platform.
|
|
</p>
|
|
|
|
<a name="n13"></a><H3>24.5.1 Customized Interpreter</H3>
|
|
|
|
|
|
<p>
|
|
We will assume your files are in a directory
|
|
<tt>/home/jonah/examples</tt>. Make a file as follows:
|
|
<pre>
|
|
;; precsi.scm
|
|
(declare (unit precsi))
|
|
(declare (uses example))
|
|
|
|
;; any other code you want run before the main interpreter is executed
|
|
</pre>
|
|
|
|
Run SWIG on your interface file as usual, create the 2 wrapper
|
|
object files, and then either
|
|
|
|
<blockquote>
|
|
<pre>
|
|
% cd /usr/local/share/chicken
|
|
% chicken /usr/local/share/chicken/src/csi.scm -optimize-level 3 -quiet \
|
|
-include-path /usr/local/share/chicken/src \
|
|
-prologue /usr/local/share/chicken/src/build.scm \
|
|
-prelude "(declare (uses posix precsi))" \
|
|
-output-file /home/jonah/examples/csi-example.c
|
|
% cd /home/jonah/examples
|
|
% chicken precsi.scm -optimize-level 3 --explicit-use \
|
|
-output-file precsi.c
|
|
% gcc precsi.c csi.c <i>wrapper_object_files</i> \
|
|
`chicken-config -libs` `chicken-config -extra-libs` -o csi-example
|
|
</pre>
|
|
<pre>
|
|
</blockquote>
|
|
or
|
|
<blockquote>
|
|
<pre>% extend-csi precsi -output-file csi-example</pre>
|
|
</blockquote>
|
|
|
|
|
|
</p>
|
|
|
|
<a name="n14"></a><H2>24.6 Typemaps</H2>
|
|
|
|
|
|
<p>
|
|
The Chicken module handles all types via typemaps. This information is
|
|
read from <code>Lib/chicken/typemaps.i</code> and
|
|
<code>Lib/chicken/chicken.swg</code>.
|
|
|
|
<br></br>
|
|
|
|
Two Chicken-specific typemaps are supported:
|
|
<code>clos_in</code> and <code>clos_out</code>. They are for
|
|
converting TinyCLOS to and from low-level CHICKEN SWIG. Here is
|
|
a quick example:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* Let "Shape" objects be converted back and forth from TinyCLOS into
|
|
low-level CHICKEN SWIG procedures */
|
|
|
|
%typemap(clos_in) Shape * = SIMPLE_CLOS_OBJECT *;
|
|
%typemap(clos_out) Shape * = SIMPLE_CLOS_OBJECT *;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The <code>SIMPLE_CLOS_OBJECT</code> will generally be all that
|
|
is needed ... the definition of this is as follows:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* TinyCLOS <--> Low-level CHICKEN */
|
|
|
|
%typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))"
|
|
%typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)"
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Now, in the example using "Shape" objects, all objects
|
|
instantiated from Shape or <em>any of its subclasses fully known
|
|
to SWIG</em> will have correct TinyCLOS representations based on
|
|
<code>SIMPLE_CLOS_OBJECT</code>. SWIG "knows" the classes that
|
|
are exposed in the SWIG interface file; it "fully knows" only
|
|
those classes that are not forward declarations.
|
|
|
|
<br></br>
|
|
|
|
A real-world example of the "fully knows" problem is found in
|
|
the VTK visualization library. All VTK classes are derived from
|
|
vtkObject.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtkObject.h */
|
|
class vtkObject {
|
|
// ...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtkWindow.h */
|
|
#include "vtkObject.h"
|
|
|
|
class vtkWindow : public vtkObject {
|
|
// ...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtkViewport.h */
|
|
#include "vtkViewport.h"
|
|
|
|
class vtkViewport : public vtkObject {
|
|
// ...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtkRenderWindow.h */
|
|
#include "vtkWindow.h"
|
|
|
|
class vtkRenderer;
|
|
class vtkRenderWindow : public vtkWindow {
|
|
// ...
|
|
virtual void AddRenderer (vtkRenderer *rendererArg);
|
|
// ...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtkRenderer.h */
|
|
#include "vtkViewport.h"
|
|
|
|
class vtkRenderWindow;
|
|
class vtkRenderer : public vtkViewport {
|
|
// ...
|
|
void SetRenderWindow(vtkRenderWindow *);
|
|
// ...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
/* FILE: vtk.i; SWIG interface file */
|
|
%typemap(clos_in) vtkObject * = SIMPLE_CLOS_OBJECT *;
|
|
%typemap(clos_out) vtkObject * = SIMPLE_CLOS_OBJECT *;
|
|
%include "vtkObject.h"
|
|
%include "vtkWindow.h"
|
|
%include "vtkViewport.h"
|
|
%include "vtkRenderWindow.h"
|
|
%include "vtkRenderer.h"
|
|
</pre>
|
|
</blockquote>
|
|
|
|
After SWIG processes <code>vtkObject.h</code> (from the
|
|
<tt>%include "vtkObject.h"</tt> line), SWIG will have the complete
|
|
definition of the <code>vtkObject</code> class because
|
|
<code>vtkObject</code> does not contain any references to any
|
|
other classes. As it reads <code>vtkWindow.h</code> and
|
|
<code>vtkViewport.h</code>, it will already have the definition of
|
|
<code>vtkObject</code>, so it will not need a <code>clos_in</code>
|
|
or <code>clos_out</code> typemap for the <code>vtkWindow</code> or
|
|
<code>vtkViewport</code> subclasses of <code>vtkObject</code>.
|
|
However, by the time SWIG gets to <tt>%include
|
|
"vtkRenderWindow.h"</tt>, it will not have the definition for the
|
|
<code>vtkRenderer</code> class, even though it is used by
|
|
<code>vtkRenderWindow</code>. We therefore <strong>must</strong>
|
|
put in <code>clos_in/clos_out</code> typemaps for
|
|
<code>vtkRenderer</code>.
|
|
|
|
</p>
|
|
|
|
<a name="n15"></a><H2>24.7 Pointers</H2>
|
|
|
|
|
|
<p>
|
|
For pointer types, SWIG uses CHICKEN tagged pointers.
|
|
|
|
A tagged pointer is an ordinary CHICKEN pointer with an
|
|
extra slot for an arbitrary Scheme object. With SWIG
|
|
CHICKEN, this Scheme object is a reference to a type-info
|
|
structure. So each pointer used as input or output from
|
|
the SWIG-generated CHICKEN wrappers will have type
|
|
information attached to it. This will let the wrappers
|
|
correctly determine which method should be called
|
|
according to the object type hierarchy exposed in the SWIG
|
|
interface files.
|
|
</p>
|
|
<p>
|
|
To construct a Scheme object from a C pointer, the wrapper code
|
|
calls the function <code>swig_new_pointer_obj()</code>, passing
|
|
stack allocation space of size SWIG_ALLOCSZ_POINTER (see
|
|
definition in Lib/chicken/chickenrun.swg and also
|
|
<code>C_alloc()</code> in the CHICKEN documentation) and a
|
|
pointer to a struct representing the pointer type.
|
|
</p>
|
|
<p>
|
|
To get the pointer represented by a CHICKEN tagged pointer, the
|
|
wrapper code calls the function <code>swig_convert_ptr()</code>,
|
|
passing a pointer to a struct representing the expected pointer
|
|
type. If the Scheme object passed was not a tagged pointer
|
|
representing a compatible pointer, a non-zero value is returned.
|
|
</p>
|
|
<p><strong>Warning:</strong> The Chicken typechecking code seems
|
|
to be broken (Bug #782468), so that type errors may not be
|
|
reported.
|
|
|
|
<a name="n16"></a><H2>24.8 Unsupported features</H2>
|
|
|
|
|
|
<ul>
|
|
<li>No exception handling.</li>
|
|
</ul>
|
|
</body>
|
|
</html> |