swig/Doc/Manual/Chicken.html
Dave Beazley 47f612c99a Doc update
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5411 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2003-11-25 21:18:30 +00:00

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>