Merged first chunk of Guile changes contributed by John Lenz.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4858 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
972acd608a
commit
34ea7f03ef
22 changed files with 1061 additions and 460 deletions
|
|
@ -11,21 +11,28 @@
|
|||
<!-- INDEX -->
|
||||
<ul>
|
||||
<li><a href="#n2">Meaning of "Module"</a>
|
||||
<li><a href="#n3">Linkage</a>
|
||||
<li><a href="#n3">Using the SCM or GH Guile API</a>
|
||||
<li><a href="#n4">Linkage</a>
|
||||
<ul>
|
||||
<li><a href="#n4">Simple Linkage</a>
|
||||
<li><a href="#n5">Passive Linkage</a>
|
||||
<li><a href="#n6">Native Guile Module Linkage</a>
|
||||
<li><a href="#n7">Old Auto-Loading Guile Module Linkage</a>
|
||||
<li><a href="#n8">Hobbit4D Linkage</a>
|
||||
<li><a href="#n9">General Remarks on Multiple SWIG Modules</a>
|
||||
<li><a href="#n5">Simple Linkage</a>
|
||||
<li><a href="#n6">Passive Linkage</a>
|
||||
<li><a href="#n7">Native Guile Module Linkage</a>
|
||||
<li><a href="#n8">Old Auto-Loading Guile Module Linkage</a>
|
||||
<li><a href="#n9">Hobbit4D Linkage</a>
|
||||
<li><a href="#n10">General Remarks on Multiple SWIG Modules</a>
|
||||
</ul>
|
||||
<li><a href="#n10">Underscore Folding</a>
|
||||
<li><a href="#n11">Typemaps</a>
|
||||
<li><a href="#n12">Smobs</a>
|
||||
<li><a href="#n13">Exception Handling</a>
|
||||
<li><a href="#n14">Procedure documentation</a>
|
||||
<li><a href="#n15">Procedures with setters</a>
|
||||
<li><a href="#n11">Underscore Folding</a>
|
||||
<li><a href="#n12">Typemaps</a>
|
||||
<li><a href="#n13">Smobs</a>
|
||||
<ul>
|
||||
<li><a href="#n14">GH API</a>
|
||||
<li><a href="#n15">SCM API</a>
|
||||
<li><a href="#n16">Garbage Collection</a>
|
||||
<!--<li><a href="#n17">GOOPS</a>-->
|
||||
</ul>
|
||||
<li><a href="#n18">Exception Handling</a>
|
||||
<li><a href="#n19">Procedure documentation</a>
|
||||
<li><a href="#n20">Procedures with setters</a>
|
||||
</ul>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
|
@ -44,7 +51,56 @@ There are three different concepts of "module" involved, defined
|
|||
separately for SWIG, Guile, and Libtool. To avoid horrible confusion,
|
||||
we explicitly prefix the context, e.g., "guile-module".
|
||||
|
||||
<a name="n3"></a><H2>14.2 Linkage</H2>
|
||||
<a name="n3"></a><H2>14.2 Using the SCM or GH Guile API</H2>
|
||||
|
||||
<p>The guile module can currently export wrapper files that use the guile GH interface or the
|
||||
SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig
|
||||
to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-gh" argument
|
||||
is the default. The "-scm" wrapper generation assumes a guile version >= 1.6 and has several advantages over
|
||||
the "-gh" wrapper generation including garbage collection and possibly GOOPS support in the future.
|
||||
The "-gh" wrapper generation can be used for older versions of guile. Thus eventually
|
||||
the guile GH wrapper code generation will be depreciated (as guile 1.6 and above become more common) and the
|
||||
SCM interface will become the default. The SCM and GH interface differ greatly in how they store
|
||||
pointers and have completly different run-time code. See below for more info.
|
||||
<code>make runtime</code> will now produce two libraries, libguilegh and libguilescm containing the
|
||||
runtime code using the two different guile API's.</p>
|
||||
|
||||
<p>The GH interface to guile is deprecated. Read more about why in the
|
||||
<a href="http://www.gnu.org/software/guile/docs/guile-ref/GH-deprecation.html">Guile manual</a>.
|
||||
The idea of the GH interface was to provide a high level API that other languages and projects
|
||||
could adopt. This was a good idea, but didn't pan out well for general development. But for the
|
||||
specific, minimal uses that the SWIG typemaps put the GH interface to use is ideal for
|
||||
using a high level API. So even though the GH interface is depreciated, SWIG will continue to use
|
||||
the GH interface and provide mappings from the GH interface to whatever API we need.
|
||||
We can maintain this mapping where guile failed because SWIG uses a small subset of all the GH functions
|
||||
which map easily. All the guile typemaps like typemaps.i and std_vector.i
|
||||
will continue to use the GH functions to do things like create lists of values, convert strings to
|
||||
integers, etc. Then every language module will define a mapping between the GH interface and
|
||||
whatever custom API the language uses. This is currently implemented by the guile module to use
|
||||
the SCM guile API rather than the GH guile API.
|
||||
For example, here are some of the current mapping file for the SCM API</p>
|
||||
|
||||
<blockquote><pre>
|
||||
|
||||
#define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED))
|
||||
#define gh_apply(a, b) scm_apply(a, b, SCM_EOL)
|
||||
#define gh_bool2scm SCM_BOOL
|
||||
#define gh_boolean_p SCM_BOOLP
|
||||
#define gh_car SCM_CAR
|
||||
#define gh_cdr SCM_CDR
|
||||
#define gh_cons scm_cons
|
||||
#define gh_double2scm scm_make_real
|
||||
...
|
||||
</pre></blockquote>
|
||||
|
||||
<p>This file is parsed by SWIG at wrapper generation time, so every reference to a gh_ function is replaced
|
||||
by a scm_ function in the wrapper file. Thus the gh_ function calls will never be seen in the wrapper;
|
||||
the wrapper will look exactly like it was generated
|
||||
for the specific API. Currently only the guile language module has created a mapping policy from gh_ to scm_,
|
||||
but there is no reason other languages (like mzscheme or chicken) couldn't also use this.
|
||||
If that happens, there is A LOT less code duplication in the standard typemaps.</p>
|
||||
|
||||
<a name="n4"></a><H2>14.3 Linkage</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -54,7 +110,7 @@ Guile support is complicated by a lack of user community cohesiveness,
|
|||
which manifests in multiple shared-library usage conventions. A set of
|
||||
policies implementing a usage convention is called a <b>linkage</b>.
|
||||
|
||||
<a name="n4"></a><H3>14.2.1 Simple Linkage</H3>
|
||||
<a name="n5"></a><H3>14.3.1 Simple Linkage</H3>
|
||||
|
||||
|
||||
The default linkage is the simplest; nothing special is done. In this
|
||||
|
|
@ -127,7 +183,7 @@ placed between the <code>define-module</code> form and the
|
|||
<code>SWIG_init</code> via a preprocessor define to avoid symbol
|
||||
clashes. For this case, however, passive linkage is available.
|
||||
|
||||
<a name="n5"></a><H3>14.2.2 Passive Linkage</H3>
|
||||
<a name="n6"></a><H3>14.3.2 Passive Linkage</H3>
|
||||
|
||||
|
||||
<p>Passive linkage is just like simple linkage, but it generates an
|
||||
|
|
@ -137,7 +193,7 @@ package name (see below).
|
|||
<p>You should use passive linkage rather than simple linkage when you
|
||||
are using multiple modules.
|
||||
|
||||
<a name="n6"></a><H3>14.2.3 Native Guile Module Linkage</H3>
|
||||
<a name="n7"></a><H3>14.3.3 Native Guile Module Linkage</H3>
|
||||
|
||||
|
||||
<p>SWIG can also generate wrapper code that does all the Guile module
|
||||
|
|
@ -178,7 +234,7 @@ Newer Guile versions have a shorthand procedure for this:
|
|||
</blockquote>
|
||||
</ul>
|
||||
|
||||
<a name="n7"></a><H3>14.2.4 Old Auto-Loading Guile Module Linkage</H3>
|
||||
<a name="n8"></a><H3>14.3.4 Old Auto-Loading Guile Module Linkage</H3>
|
||||
|
||||
|
||||
<p>Guile used to support an autoloading facility for object-code
|
||||
|
|
@ -204,7 +260,7 @@ option, SWIG generates an exported module initialization function with
|
|||
an apropriate name.
|
||||
|
||||
|
||||
<a name="n8"></a><H3>14.2.5 Hobbit4D Linkage</H3>
|
||||
<a name="n9"></a><H3>14.3.5 Hobbit4D Linkage</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -227,7 +283,7 @@ my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
|
|||
experimental; the (hobbit4d link) conventions are not well understood.
|
||||
|
||||
|
||||
<a name="n9"></a><H3>14.2.6 General Remarks on Multiple SWIG Modules</H3>
|
||||
<a name="n10"></a><H3>14.3.6 General Remarks on Multiple SWIG Modules</H3>
|
||||
|
||||
|
||||
If you want to use multiple SWIG modules, they have to share some
|
||||
|
|
@ -241,13 +297,13 @@ with the C compiler switch <code>-DSWIG_GLOBAL</code>.
|
|||
<li>Or generate all wrapper modules with the <code>-c</code>
|
||||
command-line argument and compile all wrapper files with the C
|
||||
compiler switch <code>-DSWIG_GLOBAL</code>. Then link against the
|
||||
runtime library <code>libswigguile</code>, which is built by
|
||||
runtime library <code>libswigguile</code> or <code>libswigguilescm</code>, which is built by
|
||||
<code>make runtime</code>. The needed linker flags are reported by
|
||||
SWIG if you invoke it with the <code>-guile -ldflags</code>
|
||||
command-line arguments.
|
||||
</ul>
|
||||
|
||||
<a name="n10"></a><H2>14.3 Underscore Folding</H2>
|
||||
<a name="n11"></a><H2>14.4 Underscore Folding</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -261,7 +317,7 @@ complained so far.
|
|||
<code>%rename</code> to specify the Guile name of the wrapped
|
||||
functions and variables (see CHANGES).
|
||||
|
||||
<a name="n11"></a><H2>14.4 Typemaps</H2>
|
||||
<a name="n12"></a><H2>14.5 Typemaps</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -273,8 +329,8 @@ information is read from <code>Lib/guile/typemaps.i</code>.
|
|||
Some non-standard typemap substitutions are supported:
|
||||
<ul>
|
||||
<li><code>$descriptor</code> expands to a type descriptor for use with
|
||||
the <code>SWIG_Guile_MakePtr()</code> and
|
||||
<code>SWIG_Guile_GetPtr</code> functions.
|
||||
the <code>SWIG_NewPointerObj()</code> and
|
||||
<code>SWIG_ConvertPtr</code> functions.
|
||||
<li>For pointer types, <code>$*descriptor</code> expands to a
|
||||
descriptor for the direct base type (i.e., one pointer is stripped),
|
||||
whereas <code>$basedescriptor</code> expands to a
|
||||
|
|
@ -282,7 +338,7 @@ descriptor for the base type (i.e., all pointers are stripped).
|
|||
</ul>
|
||||
|
||||
<p>A function returning <code>void</code> (more precisely, a function
|
||||
whose <code>out</code> typemap returns <code>GH_UNSPECIFIED</code>) is
|
||||
whose <code>out</code> typemap returns <code>SCM_UNSPECIFIED</code>) is
|
||||
treated as returning no values. In <code>argout</code> typemaps, one
|
||||
can use the macro <code>GUILE_APPEND_RESULT</code> in order to append
|
||||
a value to the list of function return values.
|
||||
|
|
@ -326,13 +382,27 @@ In <code><var>body</var></code>, the first result of
|
|||
</ul>
|
||||
See also the "multivalue" example.
|
||||
|
||||
<a name="n12"></a><H2>14.5 Smobs</H2>
|
||||
|
||||
|
||||
</a>
|
||||
<a name="n13"></a><H2>14.6 Smobs</H2>
|
||||
|
||||
<p>
|
||||
For pointer types, SWIG uses Guile smobs.
|
||||
For pointer types, SWIG uses Guile smobs. SWIG smobs print
|
||||
like this: <code>#<swig struct xyzzy * 0x1234affe></code> Two of
|
||||
them are <code>equal?</code> if and only if they have the same type
|
||||
and value.
|
||||
|
||||
<p>
|
||||
To construct a Scheme object from a C pointer, the wrapper code calls
|
||||
the function <code>SWIG_NewPointerObj()</code>, passing a pointer to a
|
||||
struct representing the pointer type. The type index to store in the
|
||||
upper half of the CAR is read from this struct.
|
||||
To get the pointer represented by a smob, the wrapper code calls the
|
||||
function <code>SWIG_ConvertPtr()</code>, passing a pointer to a struct
|
||||
representing the expected pointer type. See also
|
||||
<a href="Typemaps.html#n41">Section 8.8 The run-time type checker</a>.
|
||||
If the Scheme object passed was not a SWIG smob representing a compatible
|
||||
pointer, a <code>wrong-type-arg</code> exception is raised.
|
||||
|
||||
<a name="n14"></a><H3>14.6.1 GH Smobs</H3>
|
||||
|
||||
<p>
|
||||
In earlier versions of SWIG, C pointers were represented as Scheme
|
||||
|
|
@ -348,25 +418,117 @@ available. <code>SWIG_Guile_Init()</code> registers a smob type named
|
|||
"swig" with Guile; its type tag is stored in the variable
|
||||
<code>swig_tag</code>. The upper half of the CAR store an index into
|
||||
a table of all C pointer types seen so far, to which new types seen
|
||||
are appended. The CDR stores the pointer value. SWIG smobs print
|
||||
like this: <code>#<swig struct xyzzy * 0x1234affe></code> Two of
|
||||
them are <code>equal?</code> if and only if they have the same type
|
||||
and value.
|
||||
are appended. The CDR stores the pointer value.
|
||||
|
||||
<p>
|
||||
To construct a Scheme object from a C pointer, the wrapper code calls
|
||||
the function <code>SWIG_Guile_MakePtr()</code>, passing a pointer to a
|
||||
struct representing the pointer type. The type index to store in the
|
||||
upper half of the CAR is read from this struct.
|
||||
<a name="n15"></a><H3>14.6.2 SCM Smobs</H3>
|
||||
|
||||
<p>
|
||||
To get the pointer represented by a smob, the wrapper code calls the
|
||||
function <code>SWIG_Guile_GetPtr</code>, passing a pointer to a struct
|
||||
representing the expected pointer type. If the
|
||||
Scheme object passed was not a SWIG smob representing a compatible
|
||||
pointer, a <code>wrong-type-arg</code> exception is raised.
|
||||
<p>The SCM interface (using the "-scm" argument to swig) uses common.swg.
|
||||
The whole type system, when it is first initialized, creates two smobs named "swig" and "collected_swig".
|
||||
The swig smob is used for non-garbage collected smobs, while the collected_swig smob is used as described
|
||||
below. Each smob has the same format, which is a double cell created by SCM_NEWSMOB2()
|
||||
The first word of data is the pointer to the object and the second word of data is the swig_type_info *
|
||||
structure describing this type. This is a lot easier than the GH interface above because we can store
|
||||
a pointer to the type info structure right in the type. With the GH interface, there was not enough
|
||||
room in the smob to store two whole words of data so we needed to store part of the "swig_type_info address"
|
||||
in the smob tag.</p>
|
||||
|
||||
<a name="n13"></a><H2>14.6 Exception Handling</H2>
|
||||
|
||||
<a name="n16"></a><H3>14.6.3 Garbage Collection</H3>
|
||||
|
||||
<p>Garbage collection is a feature of the new SCM interface, and it is automaticlly included
|
||||
if you pass the "-scm" flag to swig. Thus the swig garbage collection support requires guile >1.6.
|
||||
Garbage collection works like this. Every swig_type_info structure stores in its clientdata field a pointer
|
||||
to the destructor for this type. The destructor is the generated wrapper around the delete function.
|
||||
So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for
|
||||
the wrapped delete function. So the only way to delete an object is from the garbage collector, since the
|
||||
delete function is not available to scripts. How swig determins if a type should be garbage collected
|
||||
is exactly like described in <a href="Customization.html#n9">
|
||||
Section 9.2 Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
|
||||
the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
|
||||
|
||||
<!--<a name="n17"></a><H3>14.6.4 GOOPS</H3>
|
||||
<p>GOOPS support is also a feature of the new SCM interface, and the "-goops" argument to swig causes
|
||||
the GOOPS class defintions to be added to the scmstub file (the "-scmstub" argument is required if the
|
||||
"-goops" argument is given.</p>
|
||||
|
||||
This is what a sample class export would look like
|
||||
<blockquote>
|
||||
<pre>
|
||||
(define-class <Foo> (<swig>)
|
||||
(a #:allocation #:swig-virtual #:slot-ref Foo-a-get #:slot-set! Foo-a-set #:accessor a)
|
||||
#:metaclass <swig-metaclass>
|
||||
|
||||
#:new-function new-Foo)
|
||||
(define-method (+ (a <Foo>) (b <Foo>))
|
||||
(make <Foo> #:init-smob (Foo-add (slot-ref a 'smob) (slot-ref b 'smob))))
|
||||
|
||||
(define <Helloo> <Foo>)
|
||||
|
||||
(define-class <Bar> (<swig>)
|
||||
(Foo #:allocation #:swig-virtual-class #:slot-ref Bar-Foo-set #:slot-set! Bar-Foo-get
|
||||
#:class <Foo> #:accessor Foo)
|
||||
#:metaclass <swig-metaclass>
|
||||
|
||||
#:new-function new-Bar)
|
||||
|
||||
(define-method (getInt (b <Bar>))
|
||||
(Bar-getInt (slot-ref b 'smob)))
|
||||
(define-method (getSqr (b <Bar>) c)
|
||||
(make <Helloo> #:init-smob (Bar-getSqr (slot-ref b 'smob) c)))
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
And the goops base class definitions will look like
|
||||
<pre>
|
||||
<blockquote>
|
||||
(define-class <swig-metaclass> (<class>)
|
||||
(new-function #:init-value #f))
|
||||
|
||||
(define-method (compute-get-n-set (class <swig-metaclass>) s)
|
||||
(case (slot-definition-allocation s)
|
||||
((#:swig-virtual)
|
||||
(list
|
||||
;getter
|
||||
(let ((func (get-keyword #:slot-ref (slot-definition-options s) #f)))
|
||||
(lambda (x) (func (slot-ref x 'smob))))
|
||||
;setter
|
||||
(let ((func (get-keyword #:slot-set! (slot-definition-options s) #f)))
|
||||
(lambda (x val) (func (slot-ref x 'smob) val)))))
|
||||
((#:swig-virtual-class)
|
||||
(list
|
||||
;getter
|
||||
(let ((func (get-keyword #:slot-ref (slot-definition-options s) #f))
|
||||
(class (get-keyword #:class (slot-definition-options s) #f)))
|
||||
(lambda (x) (make class #:init-smob (func (slot-ref x 'smob)))))
|
||||
;setter
|
||||
(let ((func (get-keyword #:slot-set! (slot-definition-options s) #f)))
|
||||
(lambda (x val) (func (slot-ref x 'smob) (func (slot-ref val 'smob)))))))
|
||||
((#:swig-new-function)
|
||||
(let ((shared-variable (slot-ref class 'new-function)))
|
||||
(list (lambda (x) shared-variable)
|
||||
(lambda (x var) (set! shared-variable var)))))
|
||||
(else (next-method))))
|
||||
|
||||
(define-method (initialize (class <swig-metaclass>) initargs)
|
||||
(slot-set! class 'new-function (get-keyword #:new-function initargs #f))
|
||||
(next-method))
|
||||
|
||||
(define-class <swig> ()
|
||||
(smob #:init-value #f)
|
||||
(new-function #:allocation #:swig-new-function)
|
||||
#:metaclass <swig-metaclass>)
|
||||
|
||||
(define-method (initialize (obj <swig>) initargs)
|
||||
(case (car initargs)
|
||||
((#:init-smob)
|
||||
(slot-set! obj 'smob (cadr initargs)))
|
||||
(else
|
||||
(slot-set! obj 'smob (apply (slot-ref obj 'new-function) initargs)))))
|
||||
|
||||
</pre>
|
||||
</blockquote>-->
|
||||
|
||||
<a name="n18"></a><H2>14.7 Exception Handling</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -392,7 +554,7 @@ mapping:
|
|||
The default when not specified here is to use "swig-error".
|
||||
See Lib/exception.i for details.
|
||||
|
||||
<a name="n14"></a><H2>14.7 Procedure documentation</H2>
|
||||
<a name="n19"></a><H2>14.8 Procedure documentation</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -429,7 +591,7 @@ typemaps <code>indoc</code>, <code>outdoc</code>,
|
|||
<code>varoutdoc</code>. See <code>Lib/guile/typemaps.i</code> for
|
||||
details.
|
||||
|
||||
<a name="n15"></a><H2>14.8 Procedures with setters</H2>
|
||||
<a name="n20"></a><H2>14.9 Procedures with setters</H2>
|
||||
|
||||
|
||||
</a>
|
||||
|
|
@ -453,4 +615,4 @@ is created, so you can use <code>(<var>struct</var>-<var>member</var>
|
|||
<var>value</var>)</code> to set it.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue