The great merge

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2002-11-30 22:01:28 +00:00
parent 5fcae5eb66
commit 12a43edc2d
1508 changed files with 125983 additions and 44037 deletions

View File

@ -3,3 +3,6 @@ Makefile
swig
*.tar.gz
configure
swig.spec
autom4te.cache
.gdbinit

View File

@ -1,54 +1,45 @@
*** ANNOUNCE: SWIG 1.3.16 ***
*** ANNOUNCE : SWIG1.3 (Alpha 5) ***
http://www.swig.org
September 22, 2000
October 14, 2002
Overview
--------
We're pleased to announce the next installment of the SWIG1.3
redevelopment effort. This release represents a reasonably stable
snapshot of the CVS repository that has undergone extensive testing
and debugging. However, this release also represents work in progress
so there may be obscure bugs and problems that we haven't found yet.
Please send us your feedback.
We're pleased to announce SWIG 1.3.16, the latest installment in the
SWIG development effort. SWIG-1.3.16 is mostly a bug-fix release to
SWIG-1.3.15.
What is SWIG?
-------------
SWIG is a software development tool that reads C/C++ header files and
generates the wrapper code needed to make C and C++ code accessible
from other languages including Perl, Python, Tcl, Ruby, PHP, Java,
Guile, Mzscheme, and Ocaml. Major applications of SWIG include
generation of scripting language extension modules, rapid prototyping,
testing, and user interface development for large C/C++ systems.
Availability:
-------------
The release is available for download on Sourceforge at
http://download.sourceforge.net/swig/swig1.3a5.tar.gz
http://prdownloads.sourceforge.net/swig/swig-1.3.16.tar.gz
What's new?
-----------
On the surface, this release still looks a lot like SWIG1.1p5 except
that a lot of bugs have been fixed and the language modules tend to
generate smaller and more efficient wrappers. New modules have also
been added to support Ruby and Mzscheme. In addition, Python, Perl,
and Guile support has been enhanced to support new releases such as
Python1.6 and Perl5.6.
Within the next day, a Windows version will also be made available at
Under the hood, you will find that this release is an almost complete
reimplementation of SWIG's internals. In fact the only code that
still remains from SWIG1.1 is the C/C++ parser and the language
modules (all of which have undergone significant changes as well). As
a result, a lot of minor improvements can be found throughout the
system and things that used to cause problems may now work (for
instance, pointers to functions are now supported). In addition, this
release incorporates a number of feature requests that have been made
on the mailing list.
http://prdownloads.sourceforge.net/swig/swigwin-1.3.16.zip
What's broken?
--------------
As this is a work in progress, a number of features are still missing
or incomplete. The documentation system is still missing and won't be
reimplemented for some time. The Java module is also temporarily out
of service for this release. In addition, C++ programmers who make
extensive use of typemaps may encounter a few strange problems
(although SWIG will generate warning messages).
Release numbers
---------------
With SWIG1.3, we are adopting an odd/even version numbering scheme for
SWIG. Odd version numbers (1.3, 1.5, 1.7, etc...) are considered to
be development releases. Even numbers (1.4,1.6,1.8) are stable
releases. The current 1.3 effort is working to produce a stable 2.0
release. A stable 2.0 release will not be made until it can
accompanied by fully updated documentation. In the meantime, we will
continue to make periodic 1.3.x releases.
We need your help!
------------------
Even if you are perfectly happy with SWIG1.1, we can use your
Even if you are perfectly happy with SWIG1.1, we can still use your
feedback. First, we like to know about compilation problems and other
issues concerning the building of SWIG. Second, if SWIG1.3 is unable
to compile your old interface files, we would like to get information
@ -56,18 +47,28 @@ about the features you are using. This information will help us find
bugs in the SWIG1.3 release, develop techniques for supporting
backwards compatibility, and write documentation that addresses
specific issues related to migrating from SWIG1.1 to SWIG1.3.
Finally, we are still looking for volunteers to work on aspects of
SWIG development. Please send email to beazley@cs.uchicago.edu for
details.
We are also looking for volunteers who would like to work on various
aspects of SWIG development. SWIG is an unfunded project that would
not exist without volunteers. We are also looking for the developers
of other SWIG language modules. If you have developed a SWIG module
and would like to see it incorporated into the new release, please
contact us to obtain SWIG-CVS access. We are also more than willing
to help port your module from SWIG1.1 to SWIG1.3. Please send email
to beazley@cs.uchicago.edu for further information.
Please report problems with this release to swig-dev@cs.uchicago.edu.
--- The SWIG Developers
David Beazley
Thien-Thi Nguyen
Matthias Köppe
Masaki Fukushima
Harco de Hilster
Loic Dachary
Oleg Tolmatcev

232
CHANGES.current Normal file
View File

@ -0,0 +1,232 @@
Version 1.3.17 (November 22, 2002)
==================================
11/19/2002: beazley
Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG.
11/19/2002: beazley
Fixed [ 615480 ] mzscheme SWIG_MustGetPtr_.
11/19/2002: beazley
Fixed [ 635119 ] SWIG_croak causes compiler warning.
11/16/2002: cheetah (William Fulton)
[Java] Added typemaps for pointers to class members.
11/15/2002: cheetah (William Fulton)
[Java] Bug fix: Overloaded C++ functions which cannot be overloaded in Java
once again issue a warning.
11/14/2002: cheetah (William Fulton)
[Java] Handling of NULL pointers is improved. A java null object will now
be translated to and from a NULL C/C++ pointer by default. Previously when
wrapping:
class SomeClass {...};
void foo(SomeClass *s);
and it was called from Java with null:
modulename.foo(null)
a Java NullPointerException was thrown. Extra typemaps had to be written in
order to obtain a NULL pointer to pass to functions like this one. Now the
default wrapping will detect 'null' and translate it into a NULL pointer.
Also if a function returns a NULL pointer, eg:
SomeClass *bar() { return NULL; }
Then this used to be wrapped with a SomeClass proxy class holding a NULL
pointer. Now null is returned instead. These changes are subtle but useful.
The original behaviour can be obtained by using the original typemaps:
%typemap(javaout) SWIGTYPE {
return new $&javaclassname($jnicall, true);
}
%typemap(javaout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
return new $javaclassname($jnicall, $owner);
}
%typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
protected static long getCPtr($javaclassname obj) {
return obj.swigCPtr;
}
%}
*** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
11/12/2002: beazley
Fixed problem with abstract methods and signatures. For example:
class abstract_foo {
public:
virtual int meth(int meth_param) = 0;
};
class abstract_bar : public abstract_foo {
public:
int meth(int meth_param_1, int meth_param_2) { return 0; }
};
In this case, abstract_bar is still abstract.
Fixes [ 628438 ] Derived abstract class not abstract.
Reported and patched by Scott Michel.
11/11/2002: beazley
Fixed a matching problem with typemaps and array dimensions. For example, if you
had this:
typedef char blah[20];
and a typemap:
%typemap() char [ANY] {
... $1_dim0 ...
}
then $1_dim* variables weren't be expanded properly. It should work now.
Problem reported by Pankaj Kumar Goel.
11/07/2002: mkoeppe
Added an experimental new module that dumps SWIG's parse
tree as (Common) Lisp s-expressions. The module is
invoked with SWIG's -sexp command-line switch. The output
can be read into Common Lisp. There is (prototype)
example Lisp code that generates Foreign Function Interface
definitions for use with Kevin Rosenberg's UFFI.
*** EXPERIMENTAL NEW FEATURE ***
11/07/2002: mkoeppe
Removed duplicate declaration of "cpp_template_decl" in
parser.y; bison 1.75 complained.
11/06/2002: cheetah (William Fulton)
[Java] Default primitive array handling has changed like arrays of classes.
C primitive arrays are no longer wrapped by a Java array but with a pointer
(type wrapper class). Again the changes have been made for efficiency reasons.
The original typemaps have been moved into arrays_java.i, so the original
behaviour can be obtained merely including this file:
%include "arrays_java.i"
The array support functions are no longer generated by default. They are only
generated when including this file, thus this often unused code is only
generated when specifically requiring this type of array support.
*** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
11/05/2002: ljohnson (Lyle Johnson)
[Ruby] Added support for nested module declarations (as was
previously added for the Perl module). So a %module directive
of the form:
%module "Outer::Inner::Foo"
will nest everything as (in Ruby code):
module Outer
module Inner
module Foo
# stuff goes here
end
end
end
11/05/2002: mkoeppe
[MzScheme] Add an argument (-declaremodule) that generates
code to correctly declare a primitive module extension.
Patch submitted by Bruce Butterfield.
11/02/2002: cheetah (William Fulton)
[Java] Added patch submitted by Michael Cahill to remove unused parameter
warnings for the jenv and cls parameters. This patch also also allows one
to use "void" in the jni typemap for any type without code being generated
attempting to return a value.
10/29/2002: cheetah (William Fulton)
[Java] Array handling is different. Arrays of classes are no longer wrapped
with proxy arrays, eg wrapping
class X {...};
X foo[10];
used to be wrapped with these Java getters and setters:
public static void setFoo(X[] value) {...}
public static X[] getFoo() {...}
This approach is very inefficient as the entire array is copied numerous
times on each invocation of the getter or setter. These arrays are now
wrapped with a pointer so it is only possible to access the first array element
using a proxy class:
public static void setFoo(X value) {...}
public static X getFoo() {...}
Arrays of enums have also been similarly changed. This behaviour is now like the
other SWIG language's implementation and the array library should be used to
access the other elements. The original behaviour can be achieved using the
macros and typemaps in arrays_java.i, for example:
%include "arrays_java.i"
JAVA_ARRAYSOFCLASSES(X)
class X {...};
X foo[10];
*** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
10/29/2002: cheetah (William Fulton)
[Java] Two new typemaps javain and javaout for generating the proxy class
and type wrapper class method calls to the JNI class. The new typemaps are
really used for transforming the jstype (used in proxy class and type wrapper
classes) to the jtype (used in the JNI class) and visa versa. A javain typemap
is required whenever an in typemap is written and similarly javaout for an out
typemap. An example is probably best to show them working:
%typemap(javain) Class "Class.getCPtr($javainput)"
%typemap(javain) unsigned short "$javainput"
%typemap(javaout) Class * {
return new Class($jnicall, $owner);
}
%inline %{
class Class {};
Class * bar(Class cls, unsigned short ush) { return new Class(); };
%}
The generated proxy code is then:
public static Class bar(Class cls, int ush) {
return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false);
}
Some new special variables have been introduced in order to use these typemaps.
Here $javainput has been replaced by 'cls' and 'ush'. $jnicall has been replaced by
the native method call, 'exampleJNI.bar(...)' and $owner has been replaced by 'false'.
$javainput is analogous to the $input special variable. It is replaced by the parameter name.
$jnicall is analogous to $action in %exception. It is replaced by the call to the native
method in the JNI class.
$owner is replaced by either true if %newobject has been used otherwise false.
The java.swg file contains default javain and javout typemaps which will produce the same code
as previously. This change is only of concern to those who have written their own typemaps as
you will then most likely have to write your own javain and javaout typemaps.
The javaout typemap also makes it possible to use a Java downcast to be used on abstract
proxy base classes. See the Java documentation on dynamic_cast.
*** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
10/24/2002: ttn
[Methodology] Upgaded to libtool 1.4.3, presumably w/ better
support for newish platforms (like MacOS X).
10/21/2002: ttn
Fixed Runtime/Makefile.in bug -- thanks to Richard Calmbach.
10/18/2002: ttn
Fixed typo in doh.h -- thanks to Max Horn.

View File

@ -81,15 +81,10 @@ observing the practices of other successful projects.
All SWIG modules must be written in either ANSI C or one of the
scripting languages for which SWIG can generate an interface (e.g.,
Perl, Python, or Tcl). <B>C++ is NOT an acceptable alternative and
will not be utilized for any future development due to the fact that
it is too complicated, too dogmatic, too problematic, and that Dave
would rather take a bullet to the head than write one more line of
code in this most decidedly unpleasant language. </B> Rare exceptions
to this rule may be made if there is a justifiable need to interface
an existing piece of software written in C++ into the SWIG module
system. Anyone who finds this rule to be unreasonable is more than
welcome to go write their own wrapper generator--so there.
Perl, Python, or Tcl). C++ is currently being used to write
SWIG modules, but it is only being utilized to avoid working with
a lot of pointers to functions. <b>Advanced C++ features like namespaces, templates,
and overloading should not be used.</b>.
<p>
Module writers should make every attempt to use only those functions

View File

@ -7,7 +7,6 @@
This directory contains SWIG documentation:
<ul>
<li><a href="whitepaper.html">Project Overview Whitepaper</a>
<li><a href="engineering.html">Engineering Manual</a>
<li><a href="internals.html">Internals Manual</a>
<li><a href="migrate.txt">SWIG1.3 Migration Guide</a>

View File

@ -51,16 +51,6 @@ beazley@cs.uchicago.edu </br>
<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>
<ul>
<li><a name="i10.1" href="#10.1">10.1 Meaning of "Module"</a>
<li><a name="i10.2" href="#10.2">10.2 Linkage</a>
<li><a name="i10.3" href="#10.3">10.3 Underscore Folding</a>
<li><a name="i10.4" href="#10.4">10.4 Typemaps</a>
<li><a name="i10.5" href="#10.5">10.5 Smobs</a>
<li><a name="i10.6" href="#10.6">10.6 Exception Handling</a>
<li><a name="i10.7" href="#10.7">10.7 Procedure documentation</a>
<li><a name="i10.8" href="#10.8">10.8 Procedures with setters</a>
</ul>
<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>
@ -940,210 +930,8 @@ for specifying local variable declarations and argument conversions.
<h2>10. Guile Support</h2>
</a>
Revised: Matthias K&ouml;ppe (August 30, 2000)
<p>
This section details guile-specific support in SWIG.
<a name="10.1" href="#i10.1">
<h3>10.1 Meaning of "Module"</h3>
</a>
<p>
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="10.2" href="#i10.2">
<h3>10.2 Linkage</h3>
</a>
<p>
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>.
The default linkage is the simplest; nothing special is done. In this
case <code>SWIG_init()</code> is provided and users must do something
like this:
<blockquote>
<pre>
(define my-so (dynamic-link "./example.so"))
(dynamic-call "SWIG_init" my-so)
</pre>
</blockquote>
At this time, the name <code>SWIG_init</code> is hardcoded; this
approach does not work with multiple swig-modules. NOTE: The "simple"
and "matrix" examples under Examples/guile include guilemain.i; the
resulting standalone interpreter does not require calls to
<code>dynamic-link</code> and <code>dynamic-call</code>, as shown here.
<p>
A second linkage creates "libtool dl module" wrappers, and currently is
broken. Whoever fixes this needs to track Guile's libtool dl module
convention, since that is not finalized.
<p>
The only other linkage supported at this time creates shared object
libraries suitable for use by hobbit's <code>(hobbit4d link)</code>
guile module. This is called the "hobbit" linkage, and requires also
using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines:
[checkme:ttn]
<blockquote>
<pre>
swig -guile -package my/lib foo.i
swig -guile -package my/lib -module foo foo.i
</pre>
</blockquote>
would create module <code>(my lib foo)</code> (assuming in the first
case foo.i declares the module to be "foo"). The installed files are
my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
experimental; the (hobbit4d link) conventions are not well understood.
<p>
There are no other linkage types planned, but that could change... To
add a new type, add the name to the enum in guile.h and add the case to
<code>GUILE::emit_linkage()</code>.
<a name="10.3" href="#i10.3">
<h3>10.3 Underscore Folding</h3>
</a>
<p>
Underscores are converted to dashes in identifiers. Guile support may
grow an option to inhibit this folding in the future, but no one has
complained so far.
<a name="10.4" href="#i10.4">
<h3>10.4 Typemaps</h3>
</a>
<p>
The Guile module handles all non-pointer types via typemaps. This
information is read from <code>Lib/guile/typemaps.i</code>.
<a name="10.5" href="#i10.5">
<h3>10.5 Smobs</h3>
</a>
<p>
For pointer types, SWIG uses Guile smobs.
<p>
Currently, one wrapper module must be generated without
<code>-c</code> and compiled with <code>-DSWIG_GLOBAL</code>, all the
other wrapper modules must be generated with <code>-c</code>. Maybe
one should move all the global helper functions that come from
<code>guile.swg</code> into a library, which is built by <code>make
runtime</code>.
<p>
In earlier versions of SWIG, C pointers were represented as Scheme
strings containing a hexadecimal rendering of the pointer value and a
mangled type name. As Guile allows registering user types, so-called
"smobs" (small objects), a much cleaner representation has been
implemented now. The details will be discussed in the following.
<p>
A smob is a cons cell where the lower half of the CAR contains the
smob type tag, while the upper half of the CAR and the whole CDR are
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>#&lt;swig struct xyzzy * 0x1234affe&gt;</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_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.
<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.
<a name="10.6" href="#i10.6">
<h3>10.6 Exception Handling</h3>
</a>
<p>
SWIG code calls <code>scm_error</code> on exception, using the following
mapping:
<pre>
MAP(SWIG_MemoryError, "swig-memory-error");
MAP(SWIG_IOError, "swig-io-error");
MAP(SWIG_RuntimeError, "swig-runtime-error");
MAP(SWIG_IndexError, "swig-index-error");
MAP(SWIG_TypeError, "swig-type-error");
MAP(SWIG_DivisionByZero, "swig-division-by-zero");
MAP(SWIG_OverflowError, "swig-overflow-error");
MAP(SWIG_SyntaxError, "swig-syntax-error");
MAP(SWIG_ValueError, "swig-value-error");
MAP(SWIG_SystemError, "swig-system-error");
</pre>
<p>
The default when not specified here is to use "swig-error".
See Lib/exception.i for details.
<a name="10.7" href="#i10.7">
<h3>10.7 Procedure documentation</h3>
</a>
<p>If invoked with the command-line option <code>-procdoc
<var>file</var></code>, SWIG creates documentation strings for the
generated wrapper functions, describing the procedure signature and
return value, and writes them to <var>file</var>.
<p>You need to register the generated documentation file with Guile
like this:
<pre>
(use-modules (ice-9 documentation))
(set! documentation-files
(cons "<var>file</var>" documentation-files))
</pre>
This requires Guile 1.4 or later.
<p>Documentation strings can be configured using the Guile-specific
typemaps <code>indoc</code>, <code>outdoc</code>,
<code>argoutdoc</code>, <code>varindoc</code>, and
<code>varoutdoc</code>. See <code>Lib/guile/typemaps.i</code> for
details.
<a name="10.8" href="#i10.8">
<h3>10.8 Procedures with setters</h3>
</a>
<p>For global variables, SWIG creates a single wrapper procedure
<code>(<var>variable</var> :optional value)</code>, which is used for
both getting and setting the value. For struct members, SWIG creates
two wrapper procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer value)</code>.
<p>If invoked with the command-line option <code>-emit-setters</code>,
SWIG will additionally create procedures with setters. For global
variables, the procedure-with-setter <code><var>variable</var></code>
is created, so you can use <code>(<var>variable</var>)</code> to get
the value and <code>(set! (<var>variable</var>)
<var>value</var>)</code> to set it. For struct members, the
procedure-with-setter <code><var>struct</var>-<var>member</var></code>
is created, so you can use <code>(<var>struct</var>-<var>member</var>
<var>pointer</var>)</code> to get the value and <code>(set!
(<var>struct</var>-<var>member</var> <var>pointer</var>)
<var>value</var>)</code> to set it.
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>

54
Doc/Manual/About.html Normal file
View File

@ -0,0 +1,54 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>About this manual</title>
</head>
<body bgcolor="#ffffff">
<h1>About This Manual</h1><p>
The HTML version of the SWIG Users Manual is a direct translation
of the printed version which is produced using Framemaker 5. The
conversion process was roughly as follows :
<ul>
<li> Raw HTML was produced using Framemaker 5 and Quadralay WebWorks Lite.
<li> Tables and figures were converted into GIF images.
<li> All of this output was fed into a magic Python script that cleaned
up the HTML source and merged the GIF figures into the text.
<li> A table of contents and alphabetized topic index were produced from
HTML heading tags by the same script.
<li> Each <TT>.html</TT> file was manually prefixed with the
"<!DOCTYPE html ..." jazz (boilerplate).
</ul>
While the conversion process is mostly complete, there are a few things
to keep in mind :
<ul>
<li> Some sections of preformatted text may have weird formatting
problems.
<li> Framemaker tables were converted into GIF images instead
of HTML tables--this is a little weird, but the easiest
approach for now.
<li> There may be a few minor formatting problems throughout
due to minor "glitches" that slipped through the conversion process
(although I've tried to correct as many as these as possible).
<li> The printed version of the SWIG manual is more than
300 pages long--resulting in about 670 Kbytes of HTML. The HTML version
is broken up into chapters. Each chapter is fairly well-contained, but
some may contain as many as 50 pages of printed text.
</ul>
Please report any problems with the documentation to beazley@cs.utah.edu.
<hr>
<address>
Last Modified : August 3, 1997</address>
</body>
</html>

350
Doc/Manual/Advanced.html Normal file
View File

@ -0,0 +1,350 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Published by Quadralay WebWorks HTML Lite 1.5.1 -->
<!-- And munged by Dave's special Python script -->
<html>
<head>
<title>Advanced Topics</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>13 Advanced Topics</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Creating multi-module packages</a>
<ul>
<li><a href="#n3">Runtime support (and potential problems)</a>
<li><a href="#n4">Why doesn't C++ inheritance work between modules?</a>
<li><a href="#n5">The SWIG runtime library</a>
<li><a href="#n6">A few dynamic loading gotchas</a>
</ul>
<li><a href="#n7">Dynamic Loading of C++ modules</a>
<li><a href="#n8">Inside the SWIG type-checker</a>
<ul>
<li><a href="#n9">Type equivalence</a>
<li><a href="#n10">Type casting</a>
<li><a href="#n11">Why a name based approach?</a>
<li><a href="#n12">Performance of the type-checker</a>
</ul>
</ul>
<!-- INDEX -->
<b>Caution: This chapter is under repair!</b>
<a name="n2"></a><H2>13.1 Creating multi-module packages</H2>
SWIG can be used to create packages consisting of many different modules. However, there are some technical aspects of doing this and techniques for managing the problem.<p>
<a name="n3"></a><H3>13.1.1 Runtime support (and potential problems)</H3>
All SWIG generated modules rely upon a small collection of functions that are used during run-time. These functions are primarily used for pointer type-checking, exception handling, and so on. When you run SWIG, these functions are included in the wrapper file (and declared as static). If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :<p>
<center><img src="ch11.1.png"></center><p>
<p>
This duplication of runtime libraries is usually harmless since there are no namespace conflicts and memory overhead is minimal. However, there is serious problem related to the fact that modules do not share type-information. This is particularly a problem when working with C++ (as described next).<p>
<a name="n4"></a><H3>13.1.2 Why doesn't C++ inheritance work between modules?</H3>
Consider for a moment the following two interface files :<p>
<p>
<blockquote><pre>// File : a.i
%module a
// Here is a base class
class a {
public:
a();
~a();
void foo(double);
};
// File : b.i
%module b
// Here is a derived class
%import a.i // Gets definition of base class
class b : public a {
public:
bar();
};
</pre></blockquote>
When compiled into two separate modules, the code does not work properly. In fact, you get a type error such as the following:<p>
<p>
<blockquote><pre>
[beazley@guinness shadow]$ <b>python</b>
Python 1.4 (Jan 16 1997) [GCC 2.7.2]
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
&gt;&gt;&gt; <b>from a import *</b>
&gt;&gt;&gt; <b>from b import *</b>
&gt;&gt;&gt; <b># Create a new "b"</b>
&gt;&gt;&gt; <b>b = new_b()</b>
&gt;&gt;&gt; <b># Call a function in the base class</b>
...
&gt;&gt;&gt; <b>a_foo(b,3)</b>
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ?
TypeError: Type error in argument 1 of a_foo. Expected _a_p.
&gt;&gt;&gt;
</pre></blockquote>
<p>
However, from our class definitions we know that "b" is an "a" by inheritance and there should be no type-error. This problem is directly due to the lack of type-sharing between modules. If we look closely at the module modules created here, they look like this :<p>
<center><img src="ch11.2.png"></center><p>
<p>
The type information listed shows the acceptable values for various C datatypes. In the "a" module, we see that "a" can only accept instances of itself. In the "b" module, we see that "a" can accept both "a" and "b" instances--which is correct given that a "b" is an "a" by inheritance.<p>
<p>
Unfortunately, this problem is inherent in the method by which SWIG makes modules. When we made the "a" module, we had no idea what derived classes might be used at a later time. However, it's impossible to produce the proper type information until after we know all of the derived classes. A nice problem to be sure, but one that can be fixed by making all modules share a single copy of the SWIG run-time library.<p>
<a name="n5"></a><H3>13.1.3 The SWIG runtime library</H3>
To reduce overhead and to fix type-handling problems, it is possible to share the SWIG run-time functions between multiple modules. This requires the use of the SWIG runtime library which is optionally built during SWIG installation. To use the runtime libraries, follow these steps:<p>
<p>
1. Build the SWIG run-time libraries. The <tt>SWIG/Runtime</tt> directory contains a makefile for doing this. If successfully built, you will end up with 8 files that are usually installed in <tt>/usr/local/lib</tt>.<p>
<p>
<blockquote><pre>
libswigpl.a # Perl library (static)
libswigpl.so # Perl library (shared)
libswigpy.a # Python library (static)
libswigpy.so # Python library (shared)
libswigtcl8.a # Tcl 8.x library (static)
libswigtcl8.so # Tcl 8.x library (shared)
libswigrb.a # Ruby library (static)
libswigrb.so # Ruby library (shared)
</pre></blockquote>
<p>
Note that certain libraries may be missing due to missing packages or unsupported features (like dynamic loading) on your machine.<p>
<p>
2. Compile all SWIG modules using the <tt>-c</tt> option. For example :<p>
<p>
<blockquote><pre>
% <b>swig -c -python a.i</b>
% <b>swig -c -python b.i</b>
</pre></blockquote>
The <tt>-c</tt> option tells SWIG to omit runtime support. It's now up to you to provide it separately--which we will do using our libraries.<p>
<p>
3. Build SWIG modules by linking against the appropriate runtime libraries.<p>
<p>
<blockquote><pre>
% <b>swig -c -python a.i</b>
% <b>swig -c -python b.i</b>
% <b>gcc -c a_wrap.c b_wrap.c -I/usr/local/include</b>
% <b>ld -shared a_wrap.o b_wrap.o -lswigpy -o a.so</b>
</pre></blockquote>
or if building a new executable (static linking)<p>
<p>
<blockquote><pre>
% <b>swig -c -tcl -ltclsh.i a.i</b>
% <b>gcc a_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigtcl -lm -o mytclsh</b>
</pre></blockquote>
<p>
When completed you should now end up with a collection of modules like this:<p>
<center><img src="ch11.3.png"></center><p>
<p>
<p>
In this configuration, the runtime library manages all datatypes and other information between modules. This management process is dynamic in nature--when new modules are loaded, they contribute information to the run-time system. In the C++ world, one could incrementally load classes as needed. As this process occurs, type information is updated and base-classes learn about derived classes as needed.<p>
<a name="n6"></a><H3>13.1.4 A few dynamic loading gotchas</H3>
When working with dynamic loading, it is critical to check that only one copy of the run-time library is being loaded into the system. When working with <tt>.a</tt> library files, problems can sometimes occur so there are a few approaches to the problem.<p>
<p>
1. Rebuild the scripting language executable with the SWIG runtime library attached to it. This is actually, fairly easy to do using SWIG. For example :<p>
<p>
<blockquote><pre>%module mytclsh
%{
static void *__embedfunc(void *a) { return a};
%}
void *__embedfunc(void *);
%include tclsh.i
</pre></blockquote>
<p>
Now, run SWIG and compile as follows:<p>
<p>
<blockquote><pre>
% <b>swig -c -tcl mytclsh.i</b>
% <b>gcc mytclsh_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigtcl -ldl -lm \
-o tclsh</b>
</pre></blockquote>
This produces a new executable "<tt>tclsh</tt>" that contains a copy of the SWIG runtime library. The weird <tt>__embedfunc()</tt> function is needed to force the functions in the runtime library to be included in the final executable.<p>
<p>
To make new dynamically loadable SWIG modules, simply compile as follows :<p>
<p>
<blockquote><pre>
% <b>swig -c -tcl example.i</b>
% <b>gcc -c example_wrap.c -I/usr/local/include</b>
% <b>ld -shared example_wrap.o -o example.so</b>
</pre></blockquote>
Linking against the <tt>swigtcl</tt> library is no longer necessary as all of the functions are now included in the <tt>tclsh</tt> executable and will be resolved when your module is loaded.<p>
<p>
2. Using shared library versions of the runtime library<p>
<p>
If supported on your machine, the runtime libraries will be built as shared libraries (indicated by a <tt>.so</tt>, <tt>.sl</tt>, or .<tt>dll</tt> suffix). To compile using the runtime libraries, you link process should look something like this:<p>
<blockquote><pre>
% <b>ld -shared swigtcl_wrap.o -o libswigtcl.so</b> # Irix
% <b>gcc -shared swigtcl_wrap.o -o libswigtcl.so</b> # Linux
% <b>ld -G swigtcl_wrap.o -o libswigtcl.so</b> # Solaris
</pre></blockquote>
In order for the <tt>libswigtcl.so</tt> library to work, it needs to be placed in a location where the dynamic loader can find it. Typically this is a system library directory (ie. <tt>/usr/local/lib</tt> or <tt>/usr/lib</tt>).<p>
<p>
When running with the shared libary version, you may get error messages such as the following:<p>
<p>
<blockquote><pre>Unable to locate libswigtcl.so</pre></blockquote>
This indicates that the loader was unable to find the shared libary at run-time. To find shared libaries, the loader looks through a collection of predetermined paths. If the <tt>libswigtcl.so</tt> file is not in any of these directories, it results in an error. On most machines, you can change the loader search path by changing the Unix environment variable <tt>LD_LIBRARY_PATH</tt>, e.g.<p>
<p>
<blockquote><pre>% <b>setenv LD_LIBRARY_PATH .:/home/beazley/packages/lib</b></pre></blockquote>
A somewhat better approach is to link your module with the proper path encoded. This is typically done using the `<tt>-rpath</tt>' or `<tt>-R</tt>' option to your linker (see the man page). For example:<p>
<p>
<blockquote><pre>% <b>ld -shared example_wrap.o example.o -rpath /home/beazley/packages/lib \
-L/home/beazley/packages/lib -lswigtcl.so -o example.so</b>
</pre></blockquote>
The <tt>-rpath</tt> option encodes the location of shared libraries into your modules and gets around having to set the <tt>LD_LIBRARY_PATH</tt> variable.<p>
<p>
If all else fails, pull up the man pages for your linker and start playing around.<p>
<a name="n7"></a><H2>13.2 Dynamic Loading of C++ modules</H2>
Dynamic loading of C++ modules presents a special problem for many systems. This is because C++ modules often need additional supporting code for proper initialization and operation. Static constructors are also a bit of a problem.<p>
<p>
While the process of building C++ modules is, by no means, and exact science, here are a few rules of thumb to follow :<p>
<p>
<ul>
<li>Don't use static constructors if at all possible (not always avoidable).
<li>Try linking your module with the C++ compiler using a command like `c++ -shared'. This often solves alot of problems.
<li>Sometimes it is necessary to link against special libraries. For example, modules compiled with g++ often need to be linked against the <tt>libgcc.a</tt>, <tt>libg++.a</tt>, and <tt>libstdc++.a</tt> libraries.
<li>Read the compiler and linker man pages over and over until you have them memorized (this may not help in some cases however).
<li>Search articles on Usenet, particularly in <tt>comp.lang.tcl</tt>, <tt>comp.lang.perl</tt>, <tt>comp.lang.python</tt> and <tt>comp.lang.ruby</tt>. Building C++ modules is a common problem.
</ul>
<p>
The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.<p>
<a name="n8"></a><H2>13.3 Inside the SWIG type-checker</H2>
The SWIG runtime type-checker plays a critical role in the correct operation of SWIG modules. It not only checks the validity of pointer types, but also manages C++ inheritance, and performs proper type-casting of pointers when necessary. This section provides some insight into what it does, how it works, and why it is the way it is.<p>
<a name="n9"></a><H3>13.3.1 Type equivalence</H3>
SWIG uses a name-based approach to managing pointer datatypes. For example, if you are using a pointer like "<tt>double *</tt>", the type-checker will look for a particular string representation of that datatype such as "<tt>_double_p</tt>". If no match is found, a type-error is reported.<p>
<p>
However, the matching process is complicated by the fact that datatypes may use a variety of different names. For example, the following declarations<p>
<p>
<blockquote><pre>typedef double Real;
typedef Real * RealPtr;
typedef double Float;
</pre></blockquote>
define two sets of equivalent types :<p>
<p>
<blockquote><pre>{double, Real, Float}
{RealPtr, Real *}
</pre></blockquote>
All of the types in each set are freely interchangable and the type-checker knows about the relationships by managing a table of equivalences such as the following :<p>
<blockquote><pre>
double =&gt; { Real, Float }
Real =&gt; { double, Float }
Float =&gt; { double, Real }
RealPtr =&gt; { Real * }
Real * =&gt; { RealPtr }
</pre></blockquote>
<p>
When you declare a function such as the following :<p>
<p>
<blockquote><pre>void foo(Real *a);
</pre></blockquote>
SWIG first checks to see if the argument passed is a "<tt>Real *</tt>". If not, it checks to see if it is any of the other equivalent types (<tt>double *</tt>, <tt>RealPtr</tt>, <tt>Float *</tt>). If so, the value is accepted and no error occurs.<p>
<p>
Derived versions of the various datatypes are also legal. For example, if you had a function like this,<p>
<p>
<blockquote><pre>void bar(Float ***a);
</pre></blockquote>
The type-checker will accept pointers of type <tt>double ***</tt> and <tt>Real ***.</tt> However, the type-checker does not always capture the full-range of possibilities. For example, a datatype of `<tt>RealPtr **</tt>' is equivalent to a `<tt>Float ***</tt>' but would be flagged as a type error. If you encounter this kind of problem, you can manually force SWIG to make an equivalence as follows:<p>
<p>
<blockquote><pre>// Tell the type checker that `Float_ppp' and `RealPtr_pp' are equivalent.
%init %{
SWIG_RegisterMapping("Float_ppp","RealPtr_pp",0);
%}
</pre></blockquote>
Doing this should hardly ever be necessary (I have never encountered a case where this was necessary), but if all else fails, you can force the run-time type checker into doing what you want.<p>
<p>
Type-equivalence of C++ classes is handled in a similar manner, but is encoded in a manner to support inheritance. For example, consider the following classes hierarchy :<p>
<p>
<blockquote><pre>class A { };
class B : public A { };
class C : public B { };
class D {};
class E : public C, public D {};
</pre></blockquote>
The type-checker encodes this into the following sets :<p>
<p>
<blockquote><pre>A =&gt; { B, C, E } "B isa A, C isa A, E isa A"
B =&gt; { C, E } "C isa B, E isa B"
C =&gt; { E } "E isa C"
D =&gt; { E } "E isa D"
E =&gt; { }
</pre></blockquote>
The encoding reflects the class hierarchy. For example, any object of type "A" will also accept objects of type B,C, and E because these are all derived from A. However, it is not legal to go the other way. For example, a function operating on a object from class E will not accept an object from class A.<p>
<a name="n10"></a><H3>13.3.2 Type casting</H3>
When working with C++ classes, SWIG needs to perform proper typecasting between derived and base classes. This is particularly important when working with multiple inheritance. To do this, conversion functions are created such as the following :<p>
<p>
<blockquote><pre>void *EtoA(void *ptr) {
E *in = (E *) ptr;
A *out = (A *) in; // Cast using C++
return (void *) out;
}
</pre></blockquote>
All pointers are internally represented as void *, but conversion functions are always invoked when pointer values are converted between base and derived classes in a C++ class hierarchy.<p>
<a name="n11"></a><H3>13.3.3 Why a name based approach?</H3>
SWIG uses a name-based approach to type-checking for a number of reasons :<p>
<p>
<ul>
<li>One of SWIG's main uses is code development and debugging. In this environment, the type name of an object turns out to be a useful piece of information in tracking down problems.
<li>In languages like Perl, the name of a datatype is used to determine things like packages and classes. By using datatype names we get a natural mapping between C and Perl.
<li>I believe using the original names of datatypes is more intuitive than munging them into something completely different.
</ul>
<p>
An alternative to a name based scheme would be to generate type-signatures based on the structure of a datatype. Such a scheme would result in perfect type-checking, but I think it would also result in a very confusing scripting language module. For this reason, I see SWIG sticking with the name-based approach--at least for the foreseeable future. <p>
<a name="n12"></a><H3>13.3.4 Performance of the type-checker</H3>
The type-checker performs the following steps when matching a datatype :<p>
<p>
<dl>
<dt>1. Check a pointer against the type supplied in the original C declaration. If there is a perfect match, we're done.
<dt>2. Check the supplied pointer against a cache of recently used datatypes.
<dt>3. Search for a match against the full list of equivalent datatypes.
<dt>4. If not found, report an error.
</dl>
<p>
Most well-structured C codes will find an exact match on the first attempt, providing the best possible performance. For C++ codes, it is quite common to be passing various objects of a common base-class around between functions. When base-class functions are invoked, it almost always results in a miscompare (because the type-checker is looking for the base-type). In this case, we drop down to a small cache of recently used datatypes. If we've used a pointer of the same type recently, it will be in the cache and we can match against it. For tight loops, this results in about 10-15% overhead over finding a match on the first try. Finally, as a last resort, we need to search the internal pointer tables for a match. This involves a combination of hash table lookup and linear search. If a match is found, it is placed into the cache and the result returned. If not, we finally report a type-mismatch.<p>
<p>
As a rule of thumb, C++ programs require somewhat more processing than C programs, but this seems to be avoidable. Also, keep in mind that performance penalties in the type-checker don't necessarily translate into big penalties in the overall application. Performance is most greatly affected by the efficiency of the target scripting language and the types of operations your C code is performing.<p>
<p>
<p>
<p><hr>
<address>SWIG 1.1 - Last Modified : Mon Aug 4 10:47:13 1997</address>
</body>
</html>

427
Doc/Manual/Arguments.html Normal file
View File

@ -0,0 +1,427 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Argument Handling</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>7 Argument Handling</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The typemaps.i library</a>
<ul>
<li><a href="#n3">Introduction</a>
<li><a href="#n4">Input parameters</a>
<li><a href="#n5">Output parameters</a>
<li><a href="#n6">Input/Output parameters</a>
<li><a href="#n7">Using different names</a>
</ul>
<li><a href="#n8">Applying constraints to input values</a>
<ul>
<li><a href="#n9">Simple constraint example</a>
<li><a href="#n10">Constraint methods</a>
<li><a href="#n11">Applying constraints to new datatypes</a>
</ul>
</ul>
<!-- INDEX -->
<b>Disclaimer: This chapter is under construction.</b>
<p>
In Chapter 3, SWIG's treatment of basic datatypes and pointers was
described. In particular, primitive types such as <tt>int</tt> and
<tt>double</tt> are mapped to corresponding types in the target
language. For everything else, pointers are used to refer to
structures, classes, arrays, and other user-defined datatypes.
However, in certain applications it is desirable to change SWIG's
handling of a specific datatype. For example, you might want to
return multiple values through the arguments of a function. This chapter
describes some of the techniques for doing this.
<a name="n2"></a><H2>7.1 The typemaps.i library</H2>
This section describes the <tt>typemaps.i</tt> library file--commonly used to
change certain properties of argument conversion.
<a name="n3"></a><H3>7.1.1 Introduction</H3>
Suppose you had a C function like this:
<p>
<blockquote><pre>void add(double a, double b, double *result) {
*result = a + b;
}
</pre></blockquote>
<p>
From reading the source code, it is clear that the function is storing
a value in the <tt>double *result</tt> parameter. However, since SWIG
does not examine function bodies, it has no way to know that this is
the underlying behavior.
<p>
One way to deal with this is to use the
<tt>typemaps.i</tt> library file and write interface code like this:
<p>
<blockquote><pre>// Simple example using typemaps
%module example
%include "typemaps.i"
%apply double *OUTPUT { double *result };
extern void add(double a, double b, double *result);
</pre></blockquote>
The <tt>%apply</tt> directive tells SWIG that you are going to apply
a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the
name of a rule that defines how to return an output value from an argument of type
<tt>double *</tt>. This rule gets applied to all of the datatypes
listed in curly braces-- in this case "<tt>double *result</tt>".<p>
<p>
When the resulting module is created, you can now use the function
like this (shown for Python):
<p>
<blockquote><pre>
>>> a = add(3,4)
>>> print a
7
>>>
</pre></blockquote>
In this case, you can see how the output value normally returned in
the third argument has magically been transformed into a function
return value. Clearly this makes the function much easier to use
since it is no longer necessary to manufacture a special <tt>double
*</tt> object and pass it to the function somehow.
<p>
Once a typemap has been applied to a type, it stays in effect for all future occurrences
of the type and name. For example, you could write the following:
<p>
<blockquote><pre>
%module example
%include "typemaps.i"
%apply double *OUTPUT { double *result };
extern void add(double a, double b, double *result);
extern void sub(double a, double b, double *result);
extern void mul(double a, double b, double *result);
extern void div(double a, double b, double *result);
...
</pre></blockquote>
In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow.
<p>
Typemap transformations can even be extended to multiple return values.
For example, consider this code:
<blockquote>
<pre>
%include "typemaps.i"
%apply int *OUTPUT { int *width, int *height };
// Returns a pair (width,height)
void getwinsize(int winid, int *width, int *height);
</pre>
</blockquote>
In this case, the function returns multiple values, allowing it to be used like this:
<blockquote><pre>
>>> w,h = genwinsize(wid)
>>> print w
400
>>> print h
300
>>>
</pre>
</blockquote>
<p>
It should also be noted that although the <tt>%apply</tt> directive is
used to associate typemap rules to datatypes, you can also use the
rule names directly in arguments. For example, you could write this:
<blockquote><pre>// Simple example using typemaps
%module example
%include "typemaps.i"
extern void add(double a, double b, double *OUTPUT);
</pre></blockquote>
Typemaps stay in effect until they are explicitly deleted or redefined to something
else. To clear a typemap, the <tt>%clear</tt> directive should be used. For example:
<blockquote>
<pre>
%clear double *result; // Remove all typemaps for double *result
</pre>
</blockquote>
<a name="n4"></a><H3>7.1.2 Input parameters</H3>
<p>
The following typemaps instruct SWIG that a pointer really only holds a single
input value:
<blockquote><pre>
int *INPUT
short *INPUT
long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
double *INPUT
float *INPUT
</pre></blockquote>
When used, it allows values to be passed instead of pointers. For example, consider this
function:
<blockquote><pre>
double add(double *a, double *b) {
return *a+*b;
}
</pre></blockquote>
Now, consider this SWIG interface:
<p>
<blockquote><pre>%module example
%include "typemaps.i"
...
extern double add(double *INPUT, double *INPUT);
</pre></blockquote>
When the function is used in the scripting language interpreter, it will work like this:
<p>
<blockquote><pre>
result = add(3,4)
</pre></blockquote>
<a name="n5"></a><H3>7.1.3 Output parameters</H3>
The following typemap rules tell SWIG that pointer is the output value of a
function. When used, you do not need to supply the argument when
calling the function. Instead, one or more output values are returned.
<p>
<blockquote><pre>int *OUTPUT
short *OUTPUT
long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
double *OUTPUT
float *OUTPUT
</pre></blockquote>
These methods can be used as shown in an earlier example. For example, if you have this C function :<p>
<p>
<blockquote><pre>void add(double a, double b, double *c) {
*c = a+b;
}
</pre></blockquote>
<p>
A SWIG interface file might look like this :<p>
<p>
<blockquote><pre>%module example
%include "typemaps.i"
...
extern void add(double a, double b, double *OUTPUT);
</pre></blockquote>
In this case, only a single output value is returned, but this is not
a restriction. An arbitrary number of output values can be returned by applying
the output rules to more than one argument (as shown previously).
<p>
If the function also returns a value, it is returned along with the argument. For example,
if you had this:
<blockquote><pre>
extern int foo(double a, double b, double *OUTPUT);
</pre></blockquote>
The function will return two values like this:
<blockquote>
<pre>
iresult, dresult = foo(3.5, 2)
</pre>
</blockquote>
<a name="n6"></a><H3>7.1.4 Input/Output parameters</H3>
When a pointer serves as both an input and output value you can use
the following typemaps :<p>
<blockquote><pre>
int *INOUT
short *INOUT
long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
double *INOUT
float *INOUT
</pre></blockquote>
A C function that uses this might be something like this:<p>
<p>
<blockquote><pre>void negate(double *x) {
*x = -(*x);
}
</pre></blockquote>
To make x function as both and input and output value, declare the
function like this in an interface file :<p>
<p>
<blockquote><pre>%module example
%include typemaps.i
...
extern void negate(double *INOUT);
</pre></blockquote>
Now within a script, you can simply call the function normally :<p>
<p>
<blockquote><pre>a = negate(3); # a = -3 after calling this
</pre></blockquote>
One subtle point of the <tt>INOUT</tt> rule is that many scripting languages
enforce mutability constraints on primitive objects (meaning that simple objects
like integers and strings aren't supposed to change). Because of this, you can't
just modify the object's value in place as the underlying C function does in this example.
Therefore, the <tt>INOUT</tt> rule returns the modified value as a new object
rather than directly overwriting the value of the original input object.
<p>
<b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
SWIG. Backwards compatibility is preserved, but deprecated.
<a name="n7"></a><H3>7.1.5 Using different names</H3>
As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
<tt>INOUT</tt> typemaps to different argument names. For example:
<p>
<blockquote><pre>// Make double *result an output value
%apply double *OUTPUT { double *result };
// Make Int32 *in an input value
%apply int *INPUT { Int32 *in };
// Make long *x inout
%apply long *INOUT {long *x};
</pre></blockquote>
To clear a rule, the <tt>%clear</tt> directive is used:
<p>
<blockquote><pre>%clear double *result;
%clear Int32 *in, long *x;
</pre></blockquote>
Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the
file or a matching <tt>%clear</tt> declaration.
<a name="n8"></a><H2>7.2 Applying constraints to input values</H2>
In addition to changing the handling of various input values, it is
also possible to use typemaps to apply constraints. For example, maybe you want to
insure that a value is positive, or that a pointer is non-NULL. This
can be accomplished including the <tt>constraints.i</tt> library file.
<a name="n9"></a><H3>7.2.1 Simple constraint example</H3>
The constraints library is best illustrated by the following interface
file :<p>
<p>
<blockquote><pre>// Interface file with constraints
%module example
%include "constraints.i"
double exp(double x);
double log(double POSITIVE); // Allow only positive values
double sqrt(double NONNEGATIVE); // Non-negative values only
double inv(double NONZERO); // Non-zero values
void free(void *NONNULL); // Non-NULL pointers only
</pre></blockquote>
The behavior of this file is exactly as you would expect. If any of
the arguments violate the constraint condition, a scripting language
exception will be raised. As a result, it is possible to catch bad
values, prevent mysterious program crashes and so on.<p>
<a name="n10"></a><H3>7.2.2 Constraint methods</H3>
The following constraints are currently available<p>
<blockquote><pre>
POSITIVE Any number &gt; 0 (not zero)
NEGATIVE Any number &lt; 0 (not zero)
NONNEGATIVE Any number &gt;= 0
NONPOSITIVE Any number &lt;= 0
NONZERO Nonzero number
NONNULL Non-NULL pointer (pointers only).
</pre></blockquote>
<a name="n11"></a><H3>7.2.3 Applying constraints to new datatypes</H3>
The constraints library only supports the primitive C datatypes, but it
is easy to apply it to new datatypes using <tt>%apply</tt>. For
example :<p>
<p>
<blockquote><pre>// Apply a constraint to a Real variable
%apply Number POSITIVE { Real in };
// Apply a constraint to a pointer type
%apply Pointer NONNULL { Vector * };
</pre></blockquote>
The special types of "Number" and "Pointer" can be applied to any
numeric and pointer variable type respectively. To later remove a
constraint, the <tt>%clear</tt> directive can be used :<p>
<p>
<blockquote><pre>%clear Real in;
%clear Vector *;
</pre></blockquote>
<p><hr>
<address>SWIG 1.3 - Last Modified : October 13, 2002</address>
</body>
</html>

946
Doc/Manual/Contents.html Normal file
View File

@ -0,0 +1,946 @@
<HTML>
<HEAD>
<TITLE>SWIG Users Manual</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
<H1>SWIG Users Manual</H1>
<p>
<h3><a href="Preface.html">0 Preface</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Preface.html#n2">Introduction</a>
<li><a href="Preface.html#n3">Special Introduction for Version 1.3</a>
<li><a href="Preface.html#n4">SWIG Versions</a>
<li><a href="Preface.html#n5">SWIG resources</a>
<li><a href="Preface.html#n6">Prerequisites</a>
<li><a href="Preface.html#n7">Organization of this manual</a>
<li><a href="Preface.html#n8">How to avoid reading the manual</a>
<li><a href="Preface.html#n9">Backwards Compatibility</a>
<li><a href="Preface.html#n10">Credits</a>
<li><a href="Preface.html#n11">Bug reports</a>
</ul>
<!-- INDEX -->
<h3><a href="Introduction.html">1 Introduction</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Introduction.html#n2">What is SWIG?</a>
<li><a href="Introduction.html#n3">Why use SWIG?</a>
<li><a href="Introduction.html#n4">A SWIG example</a>
<ul>
<li><a href="Introduction.html#n5">SWIG interface file</a>
<li><a href="Introduction.html#n6">The swig command</a>
<li><a href="Introduction.html#n7">Building a Perl5 module</a>
<li><a href="Introduction.html#n8">Building a Python module</a>
<li><a href="Introduction.html#n9">Shortcuts</a>
<li><a href="Introduction.html#n10">Building libraries and modules</a>
</ul>
<li><a href="Introduction.html#n11">Supported C/C++ language features</a>
<li><a href="Introduction.html#n12">Non-intrusive interface building</a>
<li><a href="Introduction.html#n13">Hands off code generation</a>
</ul>
<!-- INDEX -->
<h3><a href="Windows.html">2 Getting started on Windows </a></h3>
<!-- INDEX -->
<ul>
<li><a href="Windows.html#n2">Installation on Windows</a>
<ul>
<li><a href="Windows.html#n3">Windows Executable</a>
</ul>
<li><a href="Windows.html#n4">SWIG Windows Examples</a>
<ul>
<li><a href="Windows.html#n5">Instructions for using the Examples with Visual C++</a>
<ul>
<li><a href="Windows.html#n6">Python</a>
<li><a href="Windows.html#n7">TCL</a>
<li><a href="Windows.html#n8">Perl</a>
<li><a href="Windows.html#n9">Java</a>
<li><a href="Windows.html#n10">Ruby</a>
</ul>
<li><a href="Windows.html#n11">Instructions for using the Examples with other compilers</a>
</ul>
<li><a href="Windows.html#n12">SWIG on Cygwin and Mingw</a>
<ul>
<li><a href="Windows.html#n13">Building swig.exe on Windows</a>
<ul>
<li><a href="Windows.html#n14">Building swig.exe using Cygwin and Mingw</a>
<li><a href="Windows.html#n15">Building swig.exe alternatives</a>
</ul>
<li><a href="Windows.html#n16">Running the examples on Windows using Cygwin</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Scripting.html">3 Scripting Languages</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Scripting.html#n2">The two language view of the world</a>
<li><a href="Scripting.html#n3">How does a scripting language talk to C?</a>
<ul>
<li><a href="Scripting.html#n4">Wrapper functions</a>
<li><a href="Scripting.html#n5">Variable linking</a>
<li><a href="Scripting.html#n6">Constants</a>
<li><a href="Scripting.html#n7">Structures and classes</a>
<li><a href="Scripting.html#n8">Shadow classes</a>
</ul>
<li><a href="Scripting.html#n9">Building scripting language extensions</a>
<ul>
<li><a href="Scripting.html#n10">Shared libraries and dynamic loading</a>
<li><a href="Scripting.html#n11">Linking with shared libraries</a>
<li><a href="Scripting.html#n12">Static linking</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="SWIG.html">4 SWIG Basics</a></h3>
<!-- INDEX -->
<ul>
<li><a href="SWIG.html#n2">Running SWIG</a>
<ul>
<li><a href="SWIG.html#n3">Input format</a>
<li><a href="SWIG.html#n4">SWIG Output</a>
<li><a href="SWIG.html#n5">Comments</a>
<li><a href="SWIG.html#n6">C Preprocessor</a>
<li><a href="SWIG.html#n7">SWIG Directives</a>
<li><a href="SWIG.html#n8">Parser Limitations</a>
</ul>
<li><a href="SWIG.html#n9">Wrapping Simple C Declarations</a>
<ul>
<li><a href="SWIG.html#n10">Basic Type Handling</a>
<li><a href="SWIG.html#n11">Global Variables</a>
<li><a href="SWIG.html#n12">Constants</a>
<li><a href="SWIG.html#n13">A brief word about <tt>const</tt></a>
<li><a href="SWIG.html#n14">A cautionary tale of <tt>char *</tt></a>
</ul>
<li><a href="SWIG.html#n15">Pointers and complex objects</a>
<ul>
<li><a href="SWIG.html#n16">Simple pointers</a>
<li><a href="SWIG.html#n17">Run time pointer type checking</a>
<li><a href="SWIG.html#n18">Derived types, structs, and classes</a>
<li><a href="SWIG.html#n19">Undefined datatypes</a>
<li><a href="SWIG.html#n20">Typedef</a>
</ul>
<li><a href="SWIG.html#n21">Other Practicalities</a>
<ul>
<li><a href="SWIG.html#n22">Passing structures by value</a>
<li><a href="SWIG.html#n23">Return by value</a>
<li><a href="SWIG.html#n24">Linking to structure variables</a>
<li><a href="SWIG.html#n25">Linking to <tt>char *</tt></a>
<li><a href="SWIG.html#n26">Arrays</a>
<li><a href="SWIG.html#n27">Creating read-only variables</a>
<li><a href="SWIG.html#n28">Renaming and ignoring declarations</a>
<li><a href="SWIG.html#n29">Default/optional arguments</a>
<li><a href="SWIG.html#n30">Pointers to functions and callbacks</a>
</ul>
<li><a href="SWIG.html#n31">Structures and unions</a>
<ul>
<li><a href="SWIG.html#n32">Typedef and structures</a>
<li><a href="SWIG.html#n33">Character strings and structures</a>
<li><a href="SWIG.html#n34">Array members</a>
<li><a href="SWIG.html#n35">Structure data members</a>
<li><a href="SWIG.html#n36">C constructors and destructors </a>
<li><a href="SWIG.html#n37">Adding member functions to C structures</a>
<li><a href="SWIG.html#n38">Nested structures</a>
<li><a href="SWIG.html#n39">Other things to note about structure wrapping</a>
</ul>
<li><a href="SWIG.html#n40">Code Insertion</a>
<ul>
<li><a href="SWIG.html#n41">The output of SWIG</a>
<li><a href="SWIG.html#n42">Code insertion blocks</a>
<li><a href="SWIG.html#n43">Inlined code blocks</a>
<li><a href="SWIG.html#n44">Initialization blocks</a>
</ul>
<li><a href="SWIG.html#n45">An Interface Building Strategy</a>
<ul>
<li><a href="SWIG.html#n46">Preparing a C program for SWIG</a>
<li><a href="SWIG.html#n47">The SWIG interface file</a>
<li><a href="SWIG.html#n48">Why use separate interface files?</a>
<li><a href="SWIG.html#n49">Getting the right header files</a>
<li><a href="SWIG.html#n50">What to do with main()</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="SWIGPlus.html">5 SWIG and C++</a></h3>
<!-- INDEX -->
<ul>
<li><a href="SWIGPlus.html#n2">Comments on C++ Wrapping</a>
<li><a href="SWIGPlus.html#n3">Approach</a>
<li><a href="SWIGPlus.html#n4">Supported C++ features</a>
<li><a href="SWIGPlus.html#n5">Command line options and compilation</a>
<li><a href="SWIGPlus.html#n6">Simple C++ wrapping</a>
<ul>
<li><a href="SWIGPlus.html#n7">Constructors and destructors</a>
<li><a href="SWIGPlus.html#n8">Copy constructors</a>
<li><a href="SWIGPlus.html#n9">Member functions</a>
<li><a href="SWIGPlus.html#n10">Static members</a>
<li><a href="SWIGPlus.html#n11">Member functions and default arguments</a>
<li><a href="SWIGPlus.html#n12">Member data</a>
</ul>
<li><a href="SWIGPlus.html#n13">Protection</a>
<li><a href="SWIGPlus.html#n14">Enums and constants</a>
<li><a href="SWIGPlus.html#n15">Friends</a>
<li><a href="SWIGPlus.html#n16">References and pointers</a>
<li><a href="SWIGPlus.html#n17">Pass and return by value</a>
<li><a href="SWIGPlus.html#n18">Inheritance</a>
<li><a href="SWIGPlus.html#n19">A brief discussion of multiple inheritance, pointers, and type checking</a>
<li><a href="SWIGPlus.html#n20">Renaming</a>
<li><a href="SWIGPlus.html#n21">Wrapping Overloaded Functions and Methods</a>
<ul>
<li><a href="SWIGPlus.html#n22">Dispatch function generation</a>
<li><a href="SWIGPlus.html#n23">Ambiguity in Overloading</a>
<li><a href="SWIGPlus.html#n24">Ambiguity resolution and renaming</a>
<li><a href="SWIGPlus.html#n25">Comments on overloading</a>
</ul>
<li><a href="SWIGPlus.html#n26">Wrapping overloaded operators</a>
<li><a href="SWIGPlus.html#n27">Class extension</a>
<li><a href="SWIGPlus.html#n28">Templates</a>
<li><a href="SWIGPlus.html#n29">Namespaces</a>
<li><a href="SWIGPlus.html#n30">Exception specifiers</a>
<li><a href="SWIGPlus.html#n31">Pointers to Members</a>
<li><a href="SWIGPlus.html#n32">Smart pointers and operator-&gt;()</a>
<li><a href="SWIGPlus.html#n33">Using declarations and inheritance</a>
<li><a href="SWIGPlus.html#n34">Partial class definitions</a>
<li><a href="SWIGPlus.html#n35">A brief rant about const-correctness</a>
<li><a href="SWIGPlus.html#n36">Proxy classes</a>
<li><a href="SWIGPlus.html#n37">Where to go for more information</a>
</ul>
<!-- INDEX -->
<h3><a href="Preprocessor.html">6 Preprocessing</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Preprocessor.html#n2">File inclusion</a>
<li><a href="Preprocessor.html#n3">File imports</a>
<li><a href="Preprocessor.html#n4">Conditional Compilation</a>
<li><a href="Preprocessor.html#n5">Macro Expansion</a>
<li><a href="Preprocessor.html#n6">SWIG Macros</a>
<li><a href="Preprocessor.html#n7">C99 Extensions</a>
<li><a href="Preprocessor.html#n8">Preprocessing and %{ ... %} blocks</a>
<li><a href="Preprocessor.html#n9">Preprocessing and { ... }</a>
</ul>
<!-- INDEX -->
<h3><a href="Arguments.html">7 Argument Handling</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Arguments.html#n2">The typemaps.i library</a>
<ul>
<li><a href="Arguments.html#n3">Introduction</a>
<li><a href="Arguments.html#n4">Input parameters</a>
<li><a href="Arguments.html#n5">Output parameters</a>
<li><a href="Arguments.html#n6">Input/Output parameters</a>
<li><a href="Arguments.html#n7">Using different names</a>
</ul>
<li><a href="Arguments.html#n8">Applying constraints to input values</a>
<ul>
<li><a href="Arguments.html#n9">Simple constraint example</a>
<li><a href="Arguments.html#n10">Constraint methods</a>
<li><a href="Arguments.html#n11">Applying constraints to new datatypes</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Typemaps.html">8 Typemaps</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Typemaps.html#n2">Introduction</a>
<ul>
<li><a href="Typemaps.html#n3">Type conversion</a>
<li><a href="Typemaps.html#n4">Typemaps</a>
<li><a href="Typemaps.html#n5">Pattern matching</a>
<li><a href="Typemaps.html#n6">Reusing typemaps</a>
<li><a href="Typemaps.html#n7">What can be done with typemaps?</a>
<li><a href="Typemaps.html#n8">What can't be done with typemaps?</a>
<li><a href="Typemaps.html#n9">The rest of this chapter</a>
</ul>
<li><a href="Typemaps.html#n10">Typemap specifications</a>
<ul>
<li><a href="Typemaps.html#n11">Defining a typemap</a>
<li><a href="Typemaps.html#n12">Typemap scope</a>
<li><a href="Typemaps.html#n13">Copying a typemap</a>
<li><a href="Typemaps.html#n14">Deleting a typemap</a>
<li><a href="Typemaps.html#n15">Placement of typemaps</a>
</ul>
<li><a href="Typemaps.html#n16">Pattern matching rules</a>
<ul>
<li><a href="Typemaps.html#n17">Basic matching rules</a>
<li><a href="Typemaps.html#n18">Typedef reductions</a>
<li><a href="Typemaps.html#n19">Default typemaps</a>
<li><a href="Typemaps.html#n20">Multi-arguments typemaps</a>
</ul>
<li><a href="Typemaps.html#n21">Code generation rules</a>
<ul>
<li><a href="Typemaps.html#n22">Scope</a>
<li><a href="Typemaps.html#n23">Declaring new local variables</a>
<li><a href="Typemaps.html#n24">Special variables</a>
</ul>
<li><a href="Typemaps.html#n25">Common typemap methods</a>
<ul>
<li><a href="Typemaps.html#n26">"in" typemap</a>
<li><a href="Typemaps.html#n27">"out" typemap</a>
<li><a href="Typemaps.html#n28">"arginit" typemap</a>
<li><a href="Typemaps.html#n29">"default" typemap</a>
<li><a href="Typemaps.html#n30">"check" typemap</a>
<li><a href="Typemaps.html#n31">"argout" typemap</a>
<li><a href="Typemaps.html#n32">"freearg" typemap</a>
<li><a href="Typemaps.html#n33">"newfree" typemap</a>
<li><a href="Typemaps.html#n34">"memberin" typemap</a>
<li><a href="Typemaps.html#n35">"varin" typemap</a>
<li><a href="Typemaps.html#n36">"varout" typemap</a>
</ul>
<li><a href="Typemaps.html#n37">Some typemap examples</a>
<ul>
<li><a href="Typemaps.html#n38">Typemaps for arrays</a>
<li><a href="Typemaps.html#n39">Implementing constraints with typemaps</a>
</ul>
<li><a href="Typemaps.html#n40">Multi-argument typemaps</a>
<li><a href="Typemaps.html#n41">The run-time type checker</a>
<li><a href="Typemaps.html#n42">More about <tt>%apply</tt> and <tt>%clear</tt></a>
<li><a href="Typemaps.html#n43">Reducing wrapper code size</a>
<ul>
<li><a href="Typemaps.html#n44">Passing data between typemaps</a>
</ul>
<li><a href="Typemaps.html#n45">Where to go for more information?</a>
</ul>
<!-- INDEX -->
<h3><a href="Customization.html">9 Customization Features</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Customization.html#n2">Exception handling with %exception</a>
<ul>
<li><a href="Customization.html#n3">Handling exceptions in C code</a>
<li><a href="Customization.html#n4">Exception handling with longjmp()</a>
<li><a href="Customization.html#n5">Handling C++ exceptions</a>
<li><a href="Customization.html#n6">Defining different exception handlers</a>
<li><a href="Customization.html#n7">Applying exception handlers to specific datatypes.</a>
<li><a href="Customization.html#n8">Using The SWIG exception library</a>
</ul>
<li><a href="Customization.html#n9">Object ownership and %newobject</a>
<li><a href="Customization.html#n10">Features and the %feature directive</a>
</ul>
<!-- INDEX -->
<h3><a href="Varargs.html">10 Variable Length Arguments</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Varargs.html#n2">Introduction</a>
<li><a href="Varargs.html#n3">The Problem</a>
<li><a href="Varargs.html#n4">Default varargs support</a>
<li><a href="Varargs.html#n5">Argument replacement using %varargs</a>
<li><a href="Varargs.html#n6">Varargs and typemaps</a>
<li><a href="Varargs.html#n7">Varargs wrapping with libffi</a>
<li><a href="Varargs.html#n8">Wrapping of va_list</a>
<li><a href="Varargs.html#n9">C++ Issues</a>
<li><a href="Varargs.html#n10">Discussion</a>
</ul>
<!-- INDEX -->
<h3><a href="Warnings.html">11 Warning Messages</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Warnings.html#n2">Introduction</a>
<li><a href="Warnings.html#n3">Warning message suppression</a>
<li><a href="Warnings.html#n4">Enabling additional warnings</a>
<li><a href="Warnings.html#n5">Issuing a warning message</a>
<li><a href="Warnings.html#n6">Commentary</a>
<li><a href="Warnings.html#n7">Warning number reference</a>
<ul>
<li><a href="Warnings.html#n8">Deprecated features (100-199)</a>
<li><a href="Warnings.html#n9">Preprocessor (200-299)</a>
<li><a href="Warnings.html#n10">C/C++ Parser (300-399)</a>
<li><a href="Warnings.html#n11">Types and typemaps (400-499) </a>
<li><a href="Warnings.html#n12">Code generation (500-599)</a>
<li><a href="Warnings.html#n13">Language module specific (800-899) </a>
<li><a href="Warnings.html#n14">User defined (900-999)</a>
</ul>
<li><a href="Warnings.html#n15">History</a>
</ul>
<!-- INDEX -->
<h3><a href="Library.html">12 SWIG library</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Library.html#n2">The %include directive and library search path</a>
<li><a href="Library.html#n3">C Arrays and Pointers</a>
<ul>
<li><a href="Library.html#n4">cpointer.i</a>
<li><a href="Library.html#n5">carrays.i</a>
<li><a href="Library.html#n6">cmalloc.i</a>
<li><a href="Library.html#n7">cdata.i</a>
</ul>
<li><a href="Library.html#n8">C String Handling</a>
<ul>
<li><a href="Library.html#n9">Default string handling</a>
<li><a href="Library.html#n10">Passing binary data</a>
<li><a href="Library.html#n11">Using %newobject to release memory</a>
<li><a href="Library.html#n12">cstring.i</a>
</ul>
<li><a href="Library.html#n13">C++ Library</a>
<ul>
<li><a href="Library.html#n14">std_string.i</a>
<li><a href="Library.html#n15">std_vector.i</a>
</ul>
<li><a href="Library.html#n16">Utility Libraries</a>
<ul>
<li><a href="Library.html#n17">exception.i</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Advanced.html">13 Advanced Topics</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Advanced.html#n2">Creating multi-module packages</a>
<ul>
<li><a href="Advanced.html#n3">Runtime support (and potential problems)</a>
<li><a href="Advanced.html#n4">Why doesn't C++ inheritance work between modules?</a>
<li><a href="Advanced.html#n5">The SWIG runtime library</a>
<li><a href="Advanced.html#n6">A few dynamic loading gotchas</a>
</ul>
<li><a href="Advanced.html#n7">Dynamic Loading of C++ modules</a>
<li><a href="Advanced.html#n8">Inside the SWIG type-checker</a>
<ul>
<li><a href="Advanced.html#n9">Type equivalence</a>
<li><a href="Advanced.html#n10">Type casting</a>
<li><a href="Advanced.html#n11">Why a name based approach?</a>
<li><a href="Advanced.html#n12">Performance of the type-checker</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Guile.html">14 SWIG and Guile</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Guile.html#n2">Meaning of "Module"</a>
<li><a href="Guile.html#n3">Linkage</a>
<ul>
<li><a href="Guile.html#n4">Simple Linkage</a>
<li><a href="Guile.html#n5">Passive Linkage</a>
<li><a href="Guile.html#n6">Native Guile Module Linkage</a>
<li><a href="Guile.html#n7">Old Auto-Loading Guile Module Linkage</a>
<li><a href="Guile.html#n8">Hobbit4D Linkage</a>
<li><a href="Guile.html#n9">General Remarks on Multiple SWIG Modules</a>
</ul>
<li><a href="Guile.html#n10">Underscore Folding</a>
<li><a href="Guile.html#n11">Typemaps</a>
<li><a href="Guile.html#n12">Smobs</a>
<li><a href="Guile.html#n13">Exception Handling</a>
<li><a href="Guile.html#n14">Procedure documentation</a>
<li><a href="Guile.html#n15">Procedures with setters</a>
</ul>
<!-- INDEX -->
<h3><a href="Java.html">15 SWIG and Java</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Java.html#n2">Preliminaries</a>
<ul>
<li><a href="Java.html#n3">Running SWIG</a>
<li><a href="Java.html#n4">Additional Commandline Options</a>
<li><a href="Java.html#n5">Getting the right header files</a>
<li><a href="Java.html#n6">Compiling a dynamic module</a>
<li><a href="Java.html#n7">Using your module</a>
<li><a href="Java.html#n8">Compilation problems and compiling with C++</a>
</ul>
<li><a href="Java.html#n9">Building Java Extensions under Windows</a>
<ul>
<li><a href="Java.html#n10">Running SWIG from Developer Studio</a>
<li><a href="Java.html#n11">Using NMAKE</a>
</ul>
<li><a href="Java.html#n12">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="Java.html#n13">Modules, packages and generated Java classes</a>
<li><a href="Java.html#n14">Functions</a>
<li><a href="Java.html#n15">Global variables</a>
<li><a href="Java.html#n16">Constants</a>
<li><a href="Java.html#n17">Enumerations</a>
<li><a href="Java.html#n18">Pointers</a>
<li><a href="Java.html#n19">Structures</a>
<li><a href="Java.html#n20">C++ classes</a>
<li><a href="Java.html#n21">C++ inheritance</a>
<li><a href="Java.html#n22">Pointers, references, arrays and pass by value</a>
<ul>
<li><a href="Java.html#n23">Null pointers</a>
</ul>
<li><a href="Java.html#n24">C++ overloaded functions</a>
<li><a href="Java.html#n25">C++ namespaces</a>
<li><a href="Java.html#n26">C++ templates</a>
<li><a href="Java.html#n27">C++ Smart Pointers</a>
</ul>
<li><a href="Java.html#n28">Further details on the generated Java classes</a>
<ul>
<li><a href="Java.html#n29">The JNI class</a>
<ul>
<li><a href="Java.html#n30">The JNI class pragmas</a>
</ul>
<li><a href="Java.html#n31">The Java module class</a>
<ul>
<li><a href="Java.html#n32">The Java module class pragmas</a>
</ul>
<li><a href="Java.html#n33">Java proxy classes</a>
<ul>
<li><a href="Java.html#n34">Memory management</a>
<li><a href="Java.html#n35">Inheritance</a>
<li><a href="Java.html#n36">Proxy classes and garbage collection</a>
</ul>
<li><a href="Java.html#n37">Type wrapper classes</a>
</ul>
<li><a href="Java.html#n38">Common customization features</a>
<ul>
<li><a href="Java.html#n39">C/C++ helper functions</a>
<li><a href="Java.html#n40">Class extension with %extend</a>
<li><a href="Java.html#n41">Exception handling with %exception</a>
<li><a href="Java.html#n42">Method access with %javamethodmodifiers</a>
</ul>
<li><a href="Java.html#n43">Tips and techniques</a>
<ul>
<li><a href="Java.html#n44">Input and output parameters using primitive pointers and references</a>
<li><a href="Java.html#n45">Simple pointers</a>
<li><a href="Java.html#n46">Wrapping C arrays with Java arrays</a>
<li><a href="Java.html#n47">Unbounded C Arrays</a>
</ul>
<li><a href="Java.html#n48">Java typemaps</a>
<ul>
<li><a href="Java.html#n49">Default primitive type mappings</a>
<li><a href="Java.html#n50">Sixty four bit JVMs</a>
<li><a href="Java.html#n51">What is a typemap?</a>
<li><a href="Java.html#n52">Typemaps for mapping C/C++ types to Java types</a>
<li><a href="Java.html#n53">Java special variables</a>
<li><a href="Java.html#n54">Typemaps for both C and C++ compilation</a>
<li><a href="Java.html#n55">Java code typemaps</a>
</ul>
<li><a href="Java.html#n56">Typemap Examples</a>
<ul>
<li><a href="Java.html#n57">Converting Java String arrays to char ** </a>
<li><a href="Java.html#n58">Expanding a Java object to multiple arguments</a>
<li><a href="Java.html#n59">Using typemaps to return arguments</a>
<li><a href="Java.html#n60">Adding Java downcasts to polymorphic return types</a>
<li><a href="Java.html#n61">Adding an equals method to the Java classes</a>
<li><a href="Java.html#n62">Void pointers and a common Java base class</a>
</ul>
<li><a href="Java.html#n63">Odds and ends</a>
<ul>
<li><a href="Java.html#n64">JavaDoc comments</a>
<li><a href="Java.html#n65">Functional interface without proxy classes</a>
<li><a href="Java.html#n66">Dynamic linking problems</a>
<li><a href="Java.html#n67">Using your own JNI functions</a>
<li><a href="Java.html#n68">Performance concerns and hints</a>
</ul>
<li><a href="Java.html#n69">Examples</a>
</ul>
<!-- INDEX -->
<h3><a href="Ocaml.html">16 SWIG and Ocaml</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Ocaml.html#n2">Preliminaries</a>
<ul>
<li><a href="Ocaml.html#n3">Running SWIG</a>
<li><a href="Ocaml.html#n4">Getting the right header files</a>
<li><a href="Ocaml.html#n5">Compiling the code</a>
<li><a href="Ocaml.html#n6">The camlp4 module</a>
<li><a href="Ocaml.html#n7">Current thoughts on best practice for Ocaml</a>
<li><a href="Ocaml.html#n8">Using your module</a>
<li><a href="Ocaml.html#n9">Compilation problems and compiling with C++</a>
</ul>
<li><a href="Ocaml.html#n10">The low-level Ocaml/C interface</a>
<ul>
<li><a href="Ocaml.html#n11">The generated module</a>
<li><a href="Ocaml.html#n12">Enums</a>
<li><a href="Ocaml.html#n13">C++ Classes</a>
<ul>
<li><a href="Ocaml.html#n14">C++ Class Example</a>
<li><a href="Ocaml.html#n15">Compiling the example</a>
<li><a href="Ocaml.html#n16">Sample Session</a>
</ul>
<li><a href="Ocaml.html#n17">Exceptions</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Perl5.html">17 SWIG and Perl5</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Perl5.html#n2">Overview</a>
<li><a href="Perl5.html#n3">Preliminaries</a>
<ul>
<li><a href="Perl5.html#n4">Getting the right header files</a>
<li><a href="Perl5.html#n5">Compiling a dynamic module</a>
<li><a href="Perl5.html#n6">Building a dynamic module with MakeMaker</a>
<li><a href="Perl5.html#n7">Building a static version of Perl</a>
<li><a href="Perl5.html#n8">Using the module</a>
<li><a href="Perl5.html#n9">Compilation problems and compiling with C++</a>
<li><a href="Perl5.html#n10">Compiling for 64-bit platforms</a>
</ul>
<li><a href="Perl5.html#n11">Building Perl Extensions under Windows</a>
<ul>
<li><a href="Perl5.html#n12">Running SWIG from Developer Studio</a>
<li><a href="Perl5.html#n13">Using other compilers</a>
</ul>
<li><a href="Perl5.html#n14">The low-level interface</a>
<ul>
<li><a href="Perl5.html#n15">Functions</a>
<li><a href="Perl5.html#n16">Global variables</a>
<li><a href="Perl5.html#n17">Constants</a>
<li><a href="Perl5.html#n18">Pointers</a>
<li><a href="Perl5.html#n19">Structures</a>
<li><a href="Perl5.html#n20">C++ classes</a>
<li><a href="Perl5.html#n21">C++ classes and type-checking</a>
<li><a href="Perl5.html#n22">C++ overloaded functions</a>
<li><a href="Perl5.html#n23">Operators</a>
<li><a href="Perl5.html#n24">Modules and packages</a>
</ul>
<li><a href="Perl5.html#n25">Input and output parameters</a>
<li><a href="Perl5.html#n26">Exception handling </a>
<li><a href="Perl5.html#n27">Remapping datatypes with typemaps</a>
<ul>
<li><a href="Perl5.html#n28">A simple typemap example</a>
<li><a href="Perl5.html#n29">Perl5 typemaps</a>
<li><a href="Perl5.html#n30">Typemap variables</a>
<li><a href="Perl5.html#n31">Useful functions</a>
</ul>
<li><a href="Perl5.html#n32">Typemap Examples</a>
<ul>
<li><a href="Perl5.html#n33">Converting a Perl5 array to a char ** </a>
<li><a href="Perl5.html#n34">Return values </a>
<li><a href="Perl5.html#n35">Returning values from arguments</a>
<li><a href="Perl5.html#n36">Accessing array structure members</a>
<li><a href="Perl5.html#n37">Turning Perl references into C pointers</a>
<li><a href="Perl5.html#n38">Pointer handling</a>
</ul>
<li><a href="Perl5.html#n39">Proxy classes</a>
<ul>
<li><a href="Perl5.html#n40">Preliminaries</a>
<li><a href="Perl5.html#n41">Object Ownership</a>
<li><a href="Perl5.html#n42">Nested Objects</a>
<li><a href="Perl5.html#n43">Shadow Functions</a>
<li><a href="Perl5.html#n44">Inheritance</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Php.html">18 SWIG and PHP4</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Php.html#n2">Preliminaries</a>
<li><a href="Php.html#n3">Building PHP4 Extensions</a>
<ul>
<li><a href="Php.html#n4">Building a loadable extension</a>
<li><a href="Php.html#n5">Basic PHP4 interface</a>
<li><a href="Php.html#n6">Functions</a>
<li><a href="Php.html#n7">Global Variables</a>
<li><a href="Php.html#n8">Pointers </a>
<li><a href="Php.html#n9">Structures and C++ classes</a>
<li><a href="Php.html#n10">Constants</a>
<li><a href="Php.html#n11">Shadow classes</a>
<li><a href="Php.html#n12">Constructors and Destructers</a>
<li><a href="Php.html#n13">Static Member Variables</a>
<li><a href="Php.html#n14">PHP4 Pragmas</a>
<li><a href="Php.html#n15">Building extensions into php</a>
<li><a href="Php.html#n16">To be furthered...</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Python.html">19 SWIG and Python</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Python.html#n2">Overview</a>
<li><a href="Python.html#n3">Preliminaries</a>
<ul>
<li><a href="Python.html#n4">Running SWIG</a>
<li><a href="Python.html#n5">Getting the right header files</a>
<li><a href="Python.html#n6">Compiling a dynamic module</a>
<li><a href="Python.html#n7">Using distutils</a>
<li><a href="Python.html#n8">Static linking</a>
<li><a href="Python.html#n9">Using your module</a>
<li><a href="Python.html#n10">Compilation of C++ extensions</a>
<li><a href="Python.html#n11">Compiling for 64-bit platforms</a>
<li><a href="Python.html#n12">Building Python Extensions under Windows</a>
</ul>
<li><a href="Python.html#n13">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="Python.html#n14">Modules</a>
<li><a href="Python.html#n15">Functions</a>
<li><a href="Python.html#n16">Global variables</a>
<li><a href="Python.html#n17">Constants and enums</a>
<li><a href="Python.html#n18">Pointers</a>
<li><a href="Python.html#n19">Structures</a>
<li><a href="Python.html#n20">C++ classes</a>
<li><a href="Python.html#n21">C++ inheritance</a>
<li><a href="Python.html#n22">Pointers, references, values, and arrays</a>
<li><a href="Python.html#n23">C++ overloaded functions</a>
<li><a href="Python.html#n24">C++ operators</a>
<li><a href="Python.html#n25">C++ namespaces</a>
<li><a href="Python.html#n26">C++ templates</a>
<li><a href="Python.html#n27">C++ Smart Pointers</a>
</ul>
<li><a href="Python.html#n28">Further details on the Python class interface</a>
<ul>
<li><a href="Python.html#n29">Proxy classes</a>
<li><a href="Python.html#n30">Memory management</a>
<li><a href="Python.html#n31">Python 2.2 and classic classes</a>
</ul>
<li><a href="Python.html#n32">Common customization features</a>
<ul>
<li><a href="Python.html#n33">C/C++ helper functions</a>
<li><a href="Python.html#n34">Adding additional Python code</a>
<li><a href="Python.html#n35">Class extension with %extend</a>
<li><a href="Python.html#n36">Exception handling with %exception</a>
</ul>
<li><a href="Python.html#n37">Tips and techniques</a>
<ul>
<li><a href="Python.html#n38">Input and output parameters</a>
<li><a href="Python.html#n39">Simple pointers</a>
<li><a href="Python.html#n40">Unbounded C Arrays</a>
<li><a href="Python.html#n41">String handling</a>
<li><a href="Python.html#n42">Arrays</a>
<li><a href="Python.html#n43">String arrays</a>
<li><a href="Python.html#n44">STL wrappers</a>
</ul>
<li><a href="Python.html#n45">Typemaps</a>
<ul>
<li><a href="Python.html#n46">What is a typemap?</a>
<li><a href="Python.html#n47">Python typemaps</a>
<li><a href="Python.html#n48">Typemap variables</a>
<li><a href="Python.html#n49">Useful Python Functions</a>
</ul>
<li><a href="Python.html#n50">Typemap Examples</a>
<ul>
<li><a href="Python.html#n51">Converting Python list to a char ** </a>
<li><a href="Python.html#n52">Expanding a Python object into multiple arguments</a>
<li><a href="Python.html#n53">Using typemaps to return arguments</a>
<li><a href="Python.html#n54">Mapping Python tuples into small arrays</a>
<li><a href="Python.html#n55">Mapping sequences to C arrays</a>
<li><a href="Python.html#n56">Pointer handling</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Ruby.html">20 SWIG and Ruby</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Ruby.html#n2">Preliminaries</a>
<ul>
<li><a href="Ruby.html#n3">Running SWIG</a>
<li><a href="Ruby.html#n4">Getting the right header files</a>
<li><a href="Ruby.html#n5">Compiling a dynamic module</a>
<li><a href="Ruby.html#n6">Using your module</a>
<li><a href="Ruby.html#n7">Static linking</a>
<li><a href="Ruby.html#n8">Compilation of C++ extensions</a>
</ul>
<li><a href="Ruby.html#n9">Building Ruby Extensions under Windows 95/NT</a>
<ul>
<li><a href="Ruby.html#n10">Running SWIG from Developer Studio</a>
</ul>
<li><a href="Ruby.html#n11">The Ruby-to-C/C++ Mapping</a>
<ul>
<li><a href="Ruby.html#n12">Modules</a>
<li><a href="Ruby.html#n13">Functions</a>
<li><a href="Ruby.html#n14">Variable Linking</a>
<li><a href="Ruby.html#n15">Constants</a>
<li><a href="Ruby.html#n16">Pointers</a>
<li><a href="Ruby.html#n17">Structures</a>
<li><a href="Ruby.html#n18">C++ classes</a>
<li><a href="Ruby.html#n19">C++ inheritance</a>
<li><a href="Ruby.html#n20">C++ overloaded functions</a>
<li><a href="Ruby.html#n21">C++ Operators</a>
<li><a href="Ruby.html#n22">C++ namespaces</a>
<li><a href="Ruby.html#n23">C++ templates</a>
<li><a href="Ruby.html#n24">C++ Smart Pointers</a>
</ul>
<li><a href="Ruby.html#n25">Input and output parameters</a>
<li><a href="Ruby.html#n26">Simple exception handling </a>
<li><a href="Ruby.html#n27">Typemaps</a>
<ul>
<li><a href="Ruby.html#n28">What is a typemap?</a>
<li><a href="Ruby.html#n29">Ruby typemaps</a>
<li><a href="Ruby.html#n30">Typemap variables</a>
<li><a href="Ruby.html#n31">Useful Functions</a>
<ul>
<li><a href="Ruby.html#n32">C Datatypes to Ruby Objects</a>
<li><a href="Ruby.html#n33">Ruby Objects to C Datatypes</a>
<li><a href="Ruby.html#n34">Macros for VALUE</a>
<li><a href="Ruby.html#n35">Exceptions</a>
<li><a href="Ruby.html#n36">Iterators</a>
</ul>
<li><a href="Ruby.html#n37">Typemap Examples</a>
<li><a href="Ruby.html#n38">Converting a Ruby array to a char **</a>
<li><a href="Ruby.html#n39">Collecting arguments in a hash</a>
<li><a href="Ruby.html#n40">Pointer handling</a>
<ul>
<li><a href="Ruby.html#n41">Ruby Datatype Wrapping</a>
</ul>
</ul>
<li><a href="Ruby.html#n42">Operator overloading</a>
<ul>
<li><a href="Ruby.html#n43">An example (putting everything together)</a>
<li><a href="Ruby.html#n44">Expanding the example</a>
<li><a href="Ruby.html#n45">STL Vector to Ruby Array</a>
</ul>
<li><a href="Ruby.html#n46">Advanced Topics</a>
<ul>
<li><a href="Ruby.html#n47">Creating Multi-Module Packages</a>
<li><a href="Ruby.html#n48">Defining Aliases</a>
<li><a href="Ruby.html#n49">Predicate Methods</a>
<li><a href="Ruby.html#n50">Specifying Mixin Modules</a>
<li><a href="Ruby.html#n51">Interacting with Ruby's Garbage Collector</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Tcl.html">21 SWIG and Tcl</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Tcl.html#n2">Preliminaries</a>
<ul>
<li><a href="Tcl.html#n3">Getting the right header files</a>
<li><a href="Tcl.html#n4">Compiling a dynamic module</a>
<li><a href="Tcl.html#n5">Static linking</a>
<li><a href="Tcl.html#n6">Using your module</a>
<li><a href="Tcl.html#n7">Compilation of C++ extensions</a>
<li><a href="Tcl.html#n8">Compiling for 64-bit platforms</a>
<li><a href="Tcl.html#n9">Setting a package prefix</a>
<li><a href="Tcl.html#n10">Using namespaces</a>
</ul>
<li><a href="Tcl.html#n11">Building Tcl/Tk Extensions under Windows 95/NT</a>
<ul>
<li><a href="Tcl.html#n12">Running SWIG from Developer Studio</a>
<li><a href="Tcl.html#n13">Using NMAKE</a>
</ul>
<li><a href="Tcl.html#n14">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="Tcl.html#n15">Modules</a>
<li><a href="Tcl.html#n16">Functions</a>
<li><a href="Tcl.html#n17">Global variables</a>
<li><a href="Tcl.html#n18">Constants and enums</a>
<li><a href="Tcl.html#n19">Pointers</a>
<li><a href="Tcl.html#n20">Structures</a>
<li><a href="Tcl.html#n21">C++ classes</a>
<li><a href="Tcl.html#n22">C++ inheritance</a>
<li><a href="Tcl.html#n23">Pointers, references, values, and arrays</a>
<li><a href="Tcl.html#n24">C++ overloaded functions</a>
<li><a href="Tcl.html#n25">C++ operators</a>
<li><a href="Tcl.html#n26">C++ namespaces</a>
<li><a href="Tcl.html#n27">C++ templates</a>
<li><a href="Tcl.html#n28">C++ Smart Pointers</a>
</ul>
<li><a href="Tcl.html#n29">Further details on the Tcl class interface</a>
<ul>
<li><a href="Tcl.html#n30">Proxy classes</a>
<li><a href="Tcl.html#n31">Memory management</a>
</ul>
<li><a href="Tcl.html#n32">Input and output parameters</a>
<li><a href="Tcl.html#n33">Exception handling </a>
<li><a href="Tcl.html#n34">Typemaps</a>
<ul>
<li><a href="Tcl.html#n35">What is a typemap?</a>
<li><a href="Tcl.html#n36">Tcl typemaps</a>
<li><a href="Tcl.html#n37">Typemap variables</a>
<li><a href="Tcl.html#n38">Converting a Tcl list to a char ** </a>
<li><a href="Tcl.html#n39">Returning values in arguments</a>
<li><a href="Tcl.html#n40">Useful functions</a>
<li><a href="Tcl.html#n41">Standard typemaps</a>
<li><a href="Tcl.html#n42">Pointer handling</a>
</ul>
<li><a href="Tcl.html#n43">Turning a SWIG module into a Tcl Package.</a>
<li><a href="Tcl.html#n44">Building new kinds of Tcl interfaces (in Tcl)</a>
<ul>
<li><a href="Tcl.html#n45">Shadow classes</a>
</ul>
</ul>
<!-- INDEX -->
<h3><a href="Extending.html">22 Extending SWIG</a></h3>
<!-- INDEX -->
<ul>
<li><a href="Extending.html#n2">Introduction</a>
<li><a href="Extending.html#n3">Prerequisites</a>
<li><a href="Extending.html#n4">The Big Picture</a>
<li><a href="Extending.html#n5">Execution Model</a>
<ul>
<li><a href="Extending.html#n6">Preprocessing</a>
<li><a href="Extending.html#n7">Parsing</a>
<li><a href="Extending.html#n8">Parse Trees</a>
<li><a href="Extending.html#n9">Attribute namespaces</a>
<li><a href="Extending.html#n10">Symbol Tables</a>
<li><a href="Extending.html#n11">The %feature directive</a>
<li><a href="Extending.html#n12">Code Generation</a>
<li><a href="Extending.html#n13">SWIG and XML</a>
</ul>
<li><a href="Extending.html#n14">Primitive Data Structures</a>
<ul>
<li><a href="Extending.html#n15">Strings</a>
<li><a href="Extending.html#n16">Hashes</a>
<li><a href="Extending.html#n17">Lists</a>
<li><a href="Extending.html#n18">Common operations</a>
<li><a href="Extending.html#n19">I/O</a>
</ul>
<li><a href="Extending.html#n20">Navigating and manipulating parse trees</a>
<li><a href="Extending.html#n21">Working with attributes</a>
<li><a href="Extending.html#n22">Type system</a>
<ul>
<li><a href="Extending.html#n23">String encoding of types</a>
<li><a href="Extending.html#n24">Type construction</a>
<li><a href="Extending.html#n25">Type tests</a>
<li><a href="Extending.html#n26">Typedef and inheritance</a>
<li><a href="Extending.html#n27">Lvalues</a>
<li><a href="Extending.html#n28">Output functions</a>
</ul>
<li><a href="Extending.html#n29">Parameters</a>
<li><a href="Extending.html#n30">Writing a Language Module</a>
<ul>
<li><a href="Extending.html#n31">Execution model</a>
<li><a href="Extending.html#n32">Starting out</a>
<li><a href="Extending.html#n33">Command line options</a>
<li><a href="Extending.html#n34">Configuration and preprocessing</a>
<li><a href="Extending.html#n35">Entry point to code generation</a>
<li><a href="Extending.html#n36">Module I/O and wrapper skeleton</a>
<li><a href="Extending.html#n37">Low-level code generators</a>
<li><a href="Extending.html#n38">Configuration files</a>
<li><a href="Extending.html#n39">Runtime support</a>
<li><a href="Extending.html#n40">Standard library files</a>
<li><a href="Extending.html#n41">Examples and test cases</a>
<li><a href="Extending.html#n42">Documentation</a>
</ul>
<li><a href="Extending.html#n43">Typemaps</a>
<ul>
<li><a href="Extending.html#n44">Proxy classes</a>
</ul>
<li><a href="Extending.html#n45">Guide to parse tree nodes</a>
</ul>
<!-- INDEX -->
</BODY>
</HTML>

71
Doc/Manual/Copyright.html Normal file
View File

@ -0,0 +1,71 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<title> SWIG Documentation Copyright</title>
</head>
<body BGCOLOR="#FFFFFF">
<h2> SWIG Users Manual </h2>
<b>
Version 1.1<br>
June, 1997 <br>
</b>
<p>
Copyright(C) 1996, 1997<br>
All Rights Reserved<br>
<br>
David M. Beazley<br>
Department of Computer Science <br>
University of Utah <br>
Salt Lake City, Utah 84112 </br>
<tt>beazley@cs.utah.edu</tt>
<p>
This document may be freely distributed in whole or part provided this
copyright notice is retained. Commercial distribution of this document
is prohibited without the express written consent of the author.
<hr>
SWIG 1.1 is Copyright (C) 1995-1997 by the University of Utah and the
Univerity of California and distributed under the following license.
<p>
This software is copyrighted by the University of Utah and the Regents
of the University of California. The following terms apply to all
files associated with the software unless explicitly disclaimed
in individual files.
<p>
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that
(1) The above copyright notice and the following two paragraphs
appear in all copies of the source code and (2) redistributions
including binaries reproduces these notices in the supporting
documentation. Substantial modifications to this software may be
copyrighted by their authors and need not follow the licensing terms
described here, provided that the new terms are clearly indicated in
all files where they apply.
<p>
IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE
UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
<p>
THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH
SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
<hr>
<address><a href="http://www.cs.utah.edu/~beazley"> beazley@cs.utah.edu </a> <br>
Last Modified, August 3, 1997</address>
</body>
</html>

View File

@ -0,0 +1,643 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Customization Features</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>9 Customization Features</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Exception handling with %exception</a>
<ul>
<li><a href="#n3">Handling exceptions in C code</a>
<li><a href="#n4">Exception handling with longjmp()</a>
<li><a href="#n5">Handling C++ exceptions</a>
<li><a href="#n6">Defining different exception handlers</a>
<li><a href="#n7">Applying exception handlers to specific datatypes.</a>
<li><a href="#n8">Using The SWIG exception library</a>
</ul>
<li><a href="#n9">Object ownership and %newobject</a>
<li><a href="#n10">Features and the %feature directive</a>
</ul>
<!-- INDEX -->
In many cases, it is desirable to change the default wrapping of
particular declarations in an interface. For example, you might want
to provide hooks for catching C++ exceptions, add assertions, or
provide hints to the underlying code generator. This chapter
describes some of these customization techniques. First, a discussion
of exception handling is presented. Then, a more general-purpose
customization mechanism known as "features" is described.
<a name="n2"></a><H2>9.1 Exception handling with %exception</H2>
The <tt>%exception</tt> directive allows you to define a general purpose exception
handler. For example, you can specify the following:
<p>
<blockquote><pre>%exception {
try {
$action
}
catch (RangeError) {
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
return NULL;
}
}
</pre></blockquote>
<p>
When defined, the code enclosed in braces is inserted directly into the low-level wrapper
functions. The special symbol <tt>$action</tt> gets replaced with the actual operation
to be performed (a function call, method invocation, attribute access, etc.). An exception handler
remains in effect until it is explicitly deleted. This is done by using <tt>%except</tt> with
no code. For example:
<p>
<blockquote><pre>%exception; // Deletes any previously defined handler
</pre></blockquote>
<p>
<b>Compatibility note:</b> Previous versions of SWIG used a special directive <tt>%except</tt>
for exception handling. That directive is still supported but is deprecated--<tt>%exception</tt>
provides the same functionality, but is substantially more flexible.
<a name="n3"></a><H3>9.1.1 Handling exceptions in C code</H3>
C has no formal exception handling mechanism so there are several approaches that might be
used. A somewhat common technique is to simply set a special error code. For example:
<p>
<blockquote><pre>
/* File : except.c */
static char error_message[256];
static int error_status = 0;
void throw_exception(char *msg) {
strncpy(error_message,msg,256);
error_status = 1;
}
void clear_exception() {
error_status = 0;
}
char *check_exception() {
if (error_status) return error_message;
else return NULL;
}
</pre></blockquote>
To use these functions, functions simply call
<tt>throw_exception()</tt> to indicate an error occurred. For example
:<p>
<p>
<blockquote><pre>double inv(double x) {
if (x != 0) return 1.0/x;
else {
throw_exception("Division by zero");
return 0;
}
}
</pre></blockquote>
To catch the exception, you can write a simple exception handler such
as the following (shown for Perl5) :<p>
<p>
<blockquote><pre>%exception {
char *err;
clear_exception();
$action
if ((err = check_exception())) {
croak(err);
}
}
</pre></blockquote>
<p>
In this case, when an error occurs, it is translated into a Perl error.
<a name="n4"></a><H3>9.1.2 Exception handling with longjmp()</H3>
Exception handling can also be added to C code using the
<tt>&lt;setjmp.h&gt;</tt> library. Here is a minimalistic implementation that
relies on the C preprocessor :
<blockquote><pre>
/* File : except.c
Just the declaration of a few global variables we're going to use */
#include &lt;setjmp.h&gt;
jmp_buf exception_buffer;
int exception_status;
/* File : except.h */
#include &lt;setjmp.h&gt;
extern jmp_buf exception_buffer;
extern int exception_status;
#define try if ((exception_status = setjmp(exception_buffer)) == 0)
#define catch(val) else if (exception_status == val)
#define throw(val) longjmp(exception_buffer,val)
#define finally else
/* Exception codes */
#define RangeError 1
#define DivisionByZero 2
#define OutOfMemory 3
</pre></blockquote>
Now, within a C program, you can do the following :<p>
<p>
<blockquote><pre>double inv(double x) {
if (x) return 1.0/x;
else throw(DivisionByZero);
}
</pre></blockquote>
Finally, to create a SWIG exception handler, write the following :<p>
<p>
<blockquote><pre>%{
#include "except.h"
%}
%exception {
try {
$action
} catch(RangeError) {
croak("Range Error");
} catch(DivisionByZero) {
croak("Division by zero");
} catch(OutOfMemory) {
croak("Out of memory");
} finally {
croak("Unknown exception");
}
}
</pre></blockquote>
Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to
modify it to handle nested <tt>try</tt> declarations.
<a name="n5"></a><H3>9.1.3 Handling C++ exceptions</H3>
Handling C++ exceptions is also straightforward. For example:
<p>
<blockquote><pre>%exception {
try {
$action
} catch(RangeError) {
croak("Range Error");
} catch(DivisionByZero) {
croak("Division by zero");
} catch(OutOfMemory) {
croak("Out of memory");
} catch(...) {
croak("Unknown exception");
}
}
</pre></blockquote>
The exception types need to be declared as classes elsewhere, possibly
in a header file :<p>
<p>
<blockquote><pre>class RangeError {};
class DivisionByZero {};
class OutOfMemory {};
</pre>
</blockquote>
<a name="n6"></a><H3>9.1.4 Defining different exception handlers</H3>
By default, the <tt>%exception</tt> directive creates an exception
handler that is used for all wrapper functions that follow it. Unless
there is a well-defined (and simple) error handling mechanism in place,
defining one universal exception handler may be unwieldy and result
in excessive code bloat since the handler is inlined into each wrapper function.
<p>
To fix this, you can be more selective about how you use the
<tt>%exception</tt> directive. One approach is to only place it around
critical pieces of code. For example:
<p>
<blockquote><pre>%exception {
... your exception handler ...
}
/* Define critical operations that can throw exceptions here */
%exception;
/* Define non-critical operations that don't throw exceptions */
</pre></blockquote>
More precise control over exception handling can be obtained by attaching an exception handler
to specific declaration name. For example:
<blockquote>
<pre>
%exception allocate {
try {
$action
}
catch (MemoryError) {
croak("Out of memory");
}
}
</pre>
</blockquote>
In this case, the exception handler is only attached to declarations
named "allocate". This would include both global and member
functions. The names supplied to <tt>%exception</tt> follow the same
rules as for <tt>%rename</tt>. For example, if you wanted to define
an exception handler for a specific class, you might write this:
<blockquote>
<pre>
%exception Object::allocate {
try {
$action
}
catch (MemoryError) {
croak("Out of memory");
}
}
</pre>
</blockquote>
When a class prefix is supplied, the exception handler is applied to the corresponding declaration
in the specified class as well as for identically named functions appearing in derived classes.
<p>
<tt>%exception</tt> can even be used to pinpoint a precise declaration when overloading is used. For example:
<blockquote>
<pre>
%exception Object::allocate(int) {
try {
$action
}
catch (MemoryError) {
croak("Out of memory");
}
}
</pre>
</blockquote>
Attaching exceptions to specific declarations is a good way to reduce code bloat. It can also be a useful way
to attach exceptions to specific parts of a header file. For example:
<blockquote>
<pre>
%module example
%{
#include "someheader.h"
%}
// Define a few exception handlers for specific declarations
%exception Object::allocate(int) {
try {
$action
}
catch (MemoryError) {
croak("Out of memory");
}
}
%exception Object::getitem {
try {
$action
}
catch (RangeError) {
croak("Index out of range");
}
}
...
// Read a raw header file
%include "someheader.h"
</pre>
</blockquote>
<a name="n7"></a><H3>9.1.5 Applying exception handlers to specific datatypes.</H3>
An alternative approach to using the <tt>%exception</tt> directive is to
use the "except" typemap. This allows you to attach an error handler
to specific datatypes and function name. The typemap is applied to
the return value of a function. For example :<p>
<p>
<blockquote><pre>%typemap(except) void *malloc {
$action
if (!$1) {
PyExc_SetString(PyExc_MemoryError,"Out of memory in $symname");
return NULL;
}
}
void *malloc(int size);
</pre></blockquote>
When applied, this automatically checks the return value of
<tt>malloc()</tt> and raises an exception if it's invalid. For example
:<p>
<p>
<blockquote><pre>
&gt;&gt;&gt; from example import *
&gt;&gt;&gt; a = malloc(2048)
&gt;&gt;&gt; b = malloc(1500000000)
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ?
MemoryError: Out of memory in malloc
&gt;&gt;&gt;
</pre></blockquote>
When "except" typemaps are used, they override any exception handler defined with
<tt>%exception</tt>.<p>
<p>
<b>Compatibility note:</b> The except typemap dates to earlier SWIG
releases and was intended to be a mechanism for pinpointing specific
declarations. However, it never really worked that well and the new
%exception directive is much better. The except typemap is preserved for now, but
may be deprecated in future versions.
<a name="n8"></a><H3>9.1.6 Using The SWIG exception library</H3>
The <tt>exception.i</tt> library file provides support for creating
language independent exceptions in your interfaces. To use it, simply
put an "<tt>%include exception.i</tt>" in your interface file. This
creates a function<tt> SWIG_exception()</tt> that can be used to raise
common scripting language exceptions in a portable manner. For example :<p>
<p>
<blockquote><pre>// Language independent exception handler
%include exception.i
%exception {
try {
$action
} catch(RangeError) {
SWIG_exception(SWIG_ValueError, "Range Error");
} catch(DivisionByZero) {
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
} catch(OutOfMemory) {
SWIG_exception(SWIG_MemoryError, "Out of memory");
} catch(...) {
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
}
}
</pre></blockquote>
As arguments, <tt>SWIG_exception()</tt> takes an error type code (an
integer) and an error message string. The currently supported error
types are :<p>
<p>
<blockquote><pre>SWIG_MemoryError
SWIG_IOError
SWIG_RuntimeError
SWIG_IndexError
SWIG_TypeError
SWIG_DivisionByZero
SWIG_OverflowError
SWIG_SyntaxError
SWIG_ValueError
SWIG_SystemError
SWIG_UnknownError
</pre></blockquote>
<p>
Since the <tt>SWIG_exception()</tt> function is defined at the C-level
it can be used elsewhere in SWIG. This includes typemaps and helper
functions.
<a name="n9"></a><H2>9.2 Object ownership and %newobject</H2>
A common problem in some applications is managing proper ownership of objects. For
example, consider a function like this:
<blockquote>
<pre>
Foo *blah() {
Foo *f = new Foo();
return f;
}
</pre>
</blockquote>
If you wrap the function <tt>blah()</tt>, SWIG has no idea that the
return value is a newly allocated object. As a result, the resulting
extension module may produce a memory leak (SWIG is conservative and
will never delete objects unless it knows for certain that the
returned object was newly created).
<p>
To fix this, you can provide an extra hint to the code generator using
the <tt>%newobject</tt> directive. For example:
<blockquote>
<pre>
%newobject blah;
Foo *blah();
</pre>
</blockquote>
<tt>%newobject</tt> works exactly like <tt>%rename</tt> and <tt>%exception</tt>. In other words,
you can attach it to class members and parameterized declarations as before. For example:
<blockquote>
<pre>
%newobject ::blah(); // Only applies to global blah
%newobject Object::blah(int,double); // Only blah(int,double) in Object
%newobject *::copy; // Copy method in all classes
...
</pre>
</blockquote>
When <tt>%newobject</tt> is supplied, many language modules will
arrange to take ownership of the return value. This allows the value
to be automatically garbage-collected when it is no longer in use. However,
this depends entirely on the target language (a language module may choose to ignore
the <tt>%newobject</tt> directive).
<p>
Closely related to <tt>%newobject</tt> is a special typemap. The "newfree" typemap
can be used to deallocate a newly allocated return value. It is only available on
methods for which <tt>%newobject</tt> has been applied and is commonly used to clean-up string
results. For example:
<blockquote>
<pre>
%typemap(newfree) char * "free($1);";
...
%newobject strdup;
...
char *strdup(const char *s);
</pre>
</blockquote>
In this case, the result of the function is a string in the target language. Since this string
is a copy of the original result, the data returned by <tt>strdup()</tt> is no longer needed.
The "newfree" typemap in the example simply releases this memory.
<p>
<b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>,
it only applied to the next declaration. For example:
<blockquote>
<pre>
%new char *strdup(const char *s);
</pre>
</blockquote>
For now this is still supported but is deprecated.
<p>
<b>How to shoot yourself in the foot:</b> The <tt>%newobject</tt> directive is not a declaration modifier like the old
<tt>%new</tt> directive. Don't write code like this:
<blockquote>
<pre>
%newobject
char *strdup(const char *s);
</pre>
</blockquote>
The results might not be what you expect.
<a name="n10"></a><H2>9.3 Features and the %feature directive</H2>
Both <tt>%exception</tt> and <tt>%newobject</tt> are examples of a
more general purpose customization mechanism known as "features." A
feature is simply a user-definable property that is attached to
specific declarations in an interface file. Features are attached
using the <tt>%feature</tt> directive. For example:
<blockquote>
<pre>
%feature("except") Object::allocate {
try {
$action
}
catch (MemoryError) {
croak("Out of memory");
}
}
%feature("new","1") *::copy;
</pre>
</blockquote>
In fact, the <tt>%exception</tt> and <tt>%newobject</tt> directives are really nothing more than macros
involving <tt>%feature</tt>:
<blockquote>
<pre>
#define %exception %feature("except")
#define %newobject %feature("new","1")
</pre>
</blockquote>
The <tt>%feature</tt> directive follows the same name matching rules
as the <tt>%rename</tt> directive (which is in fact just a special
form of <tt>%feature</tt>). This means that features can be applied with
pinpoint accuracy to specific declarations if needed.
<p>
When a feature is defined, it is given a name and a value. Most commonly, the
value is supplied after the declaration name as shown for the <tt>"except"</tt>
example above. However, if the feature is simple, a value might be supplied
as an extra argument as shown for the <tt>"new"</tt> feature.
<p>
A feature stays in effect until it is explicitly disabled. A feature is disabled by
supplying a <tt>%feature</tt> directive with no value. For example:
<blockquote>
<pre>
%feature("except") Object::allocate; // Removes any previously defined feature
</pre>
</blockquote>
<p>
If no declaration name is given, a global feature is defined. This feature is then
attached to <em>every</em> declaration that follows. This is how global exception handlers
are defined. For example:
<blockquote>
<pre>
/* Define a global exception handler */
%feature("except") {
try {
$action
}
...
}
... bunch of declarations ...
/* Disable the exception handler */
%feature("except");
</pre>
</blockquote>
<tt>%feature</tt> is a relatively new addition to SWIG that was not added until version 1.3.10.
Its intended use is as a highly flexible customization mechanism that can be used to annotate
declarations with additional information for use by specific target language modules. For example,
in the Python module, you might use <tt>%feature</tt> to rewrite shadow class code as follows:
<blockquote>
<pre>
%module example
%rename(bar_id) bar(int,double);
// Rewrite bar() to allow some nice overloading
%feature("shadow") Foo::bar(int) %{
def bar(*args):
if len(args) == 3:
return apply(examplec.Foo_bar_id,args)
return apply(examplec.Foo_bar,args)
%}
class Foo {
public:
int bar(int x);
int bar(int x, double y);
}
</pre>
</blockquote>
As of this writing, <tt>%feature</tt> is still experimental. Further details of its
use will be described in the documentation for specific language modules.
<p><hr>
<address>SWIG 1.3 - Last Modified : December 9, 2001</address>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Documentation System</title>
</head>
<body bgcolor="#ffffff">
<h1>5 Documentation System</h1>
The documentation system is under repair and disabled in SWIG1.3. It will
return in a later release.
<p><hr>
<address>SWIG 1.3 - Last Modified : August 18, 2001</address>
</body>
</html>

2796
Doc/Manual/Extending.html Normal file

File diff suppressed because it is too large Load Diff

456
Doc/Manual/Guile.html Normal file
View File

@ -0,0 +1,456 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and Guile</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>14 SWIG and Guile</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Meaning of "Module"</a>
<li><a href="#n3">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>
</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>
</ul>
<!-- INDEX -->
<p>
This section details guile-specific support in SWIG.
<a name="n2"></a><H2>14.1 Meaning of "Module"</H2>
</a>
<p>
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>
<p>
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>
The default linkage is the simplest; nothing special is done. In this
case the function <code>SWIG_init()</code> is exported. Simple linkage
can be used in several ways:
<ul>
<li><b>Embedded Guile, no modules.</b> You want to embed a Guile
interpreter into your program; all bindings made by SWIG shall show up
in the root module. Then call <code>SWIG_init()</code> in the
<code>inner_main()</code> function. See the "simple" and "matrix" examples under
<code>Examples/guile</code>.
<li><b>Dynamic module mix-in.</b> You want to create a Guile module
using <code>define-module</code>, containing both Scheme code and
bindings made by SWIG; you want to load the SWIG modules as shared
libraries into Guile.
<blockquote>
<pre>
(define-module (my module))
(define my-so (dynamic-link "./example.so"))
(dynamic-call "SWIG_init" my-so) ; make SWIG bindings
;; Scheme definitions can go here
</pre>
</blockquote>
Newer Guile versions provide a shorthand for <code>dynamic-link</code>
and <code>dynamic-call</code>:
<blockquote>
<pre>
(load-extension "./example.so" "SWIG_init")
</pre>
</blockquote>
You need to explicitly export those bindings made by SWIG that you
want to import into other modules:
<blockquote>
<pre>
(export foo bar)
</pre>
</blockquote>
In this example, the procedures <code>foo</code> and <code>bar</code>
would be exported. Alternatively, you can export all bindings with the
following module-system hack:
<blockquote>
<pre>
(module-map (lambda (sym var)
(module-export! (current-module) (list sym)))
(current-module))
</pre>
</blockquote>
<p>SWIG can also generate this Scheme stub (from
<code>define-module</code> up to <code>export</code>)
semi-automagically if you pass it the command-line argument
<code>-scmstub <var>foo.scm</var></code>. Since SWIG doesn't know how
to load your extension module (with <code>dynamic-link</code> or
<code>load-extension</code>), you need to supply this
information by including a directive like this in the interface file:
<blockquote>
<pre>
%scheme %{ (load-extension "./example.so" "SWIG_init") %}
</pre>
</blockquote>
(The <code>%scheme</code> directive allows to insert arbitrary Scheme
code into the generated file <code><var>foo.scm</var></code>; it is
placed between the <code>define-module</code> form and the
<code>export</code> form.)
</ul>
<p>If you want to include several SWIG modules, you would need to rename
<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>
<p>Passive linkage is just like simple linkage, but it generates an
initialization function whose name is derived from the module and
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>
<p>SWIG can also generate wrapper code that does all the Guile module
declarations on its own if you pass it the <code>-Linkage
module</code> command-line option. This requires Guile 1.5.0 or later.
<p>The module name is set with the <code>-package</code> and
<code>-module</code> command-line options. Suppose you want to define
a module with name <code>(my lib foo)</code>; then you would have to
pass the options <code>-package <var>my</var>/<var>lib</var> -module
<var>foo</var></code>. Note that the last part of the name can also be set
via the SWIG directive <code>%module</code>.
<p>You can use this linkage in several ways:
<ul>
<li><b>Embedded Guile with SWIG modules.</b> You want to embed a Guile
interpreter into your program; the SWIG bindings shall be put into
different modules. Simply call the function
<code>scm_init_<var>my</var>_<var>modules</var>_<var>foo</var>_module</code>
in the <code>inner_main()</code> function.
<li><b>Dynamic Guile modules.</b> You want to load the SWIG modules as
shared libraries into Guile; all bindings are automatically put in
newly created Guile modules.
<blockquote>
<pre>
(define my-so (dynamic-link "./foo.so"))
;; create new module and put bindings there:
(dynamic-call "scm_init_my_modules_foo_module" my-so)
</pre>
</blockquote>
Newer Guile versions have a shorthand procedure for this:
<blockquote>
<pre>
(load-extension "./foo.so" "scm_init_my_modules_foo_module")
</pre>
</blockquote>
</ul>
<a name="n7"></a><H3>14.2.4 Old Auto-Loading Guile Module Linkage</H3>
<p>Guile used to support an autoloading facility for object-code
modules. This support has been marked deprecated in version 1.4.1 and
is going to disappear sooner or later. SWIG still supports building
auto-loading modules if you pass it the <code>-Linkage ltdlmod</code>
command-line option.
<p>Auto-loading worked like this: Suppose a module with name <code>(my
lib foo)</code> is required and not loaded yet. Guile will then search
all directories in its search path
for a Scheme file <code>my/modules/foo.scm</code> or a shared library
<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.so</code> (or
<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.la</code>;
see the GNU libtool documentation). If a
shared library is found that contains the symbol
<code>scm_init_<var>my</var>_<var>modules</var>_<var>foo</var>_module</code>,
the library is loaded, and the function at that symbol is called with
no arguments in order to initialize the module.
<p>When invoked with the <code>-Linkage ltdlmod</code> command-line
option, SWIG generates an exported module initialization function with
an apropriate name.
<a name="n8"></a><H3>14.2.5 Hobbit4D Linkage</H3>
<p>
The only other linkage supported at this time creates shared object
libraries suitable for use by hobbit's <code>(hobbit4d link)</code>
guile module. This is called the "hobbit" linkage, and requires also
using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines:
<blockquote>
<pre>
swig -guile -package my/lib foo.i
swig -guile -package my/lib -module foo foo.i
</pre>
</blockquote>
would create module <code>(my lib foo)</code> (assuming in the first
case foo.i declares the module to be "foo"). The installed files are
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>
If you want to use multiple SWIG modules, they have to share some
run-time data for the typing system. You have two options:
<ul>
<li>Either generate all but one wrapper module with
the <code>-c</code> command-line argument. Compile all wrapper files
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
<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>
<p>
Underscores are converted to dashes in identifiers. Guile support may
grow an option to inhibit this folding in the future, but no one has
complained so far.
<p>You can use the SWIG directives <code>%name</code> and
<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>
<p>
The Guile module handles all types via typemaps. This
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.
<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
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
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.
<p>Multiple values can be passed up to Scheme in one of three ways:
<ul>
<li><em>Multiple values as lists.</em>
By default, if more than one value is to
be returned, a list of the values is created and returned; to switch
back to this behavior, use
<blockquote>
<pre>%values_as_list;</pre>
</blockquote>
<li><em>Multiple values as vectors.</em>
By issueing
<blockquote>
<pre>%values_as_vector;</pre>
</blockquote>
vectors instead of lists will be used.
<li><em>Multiple values for multiple-value continuations.</em>
<strong>This is the most elegant way.</strong> By issueing
<blockquote>
<pre>%multiple_values;</pre>
</blockquote>
multiple values are passed to the multiple-value
continuation, as created by <code>call-with-values</code> or the
convenience macro <code>receive</code>. The latter is available if you
issue <code>(use-modules (srfi srfi-8))</code>. Assuming that your
<code>divide</code> function
wants to return two values, a quotient and a remainder, you can write:
<blockquote>
<pre>
(receive (quotient remainder)
(divide 35 17)
<var>body</var>...)
</pre>
</blockquote>
In <code><var>body</var></code>, the first result of
<code>divide</code> will be bound to the variable
<code>quotient</code>, and the second result to <code>remainder</code>.
</ul>
See also the "multivalue" example.
<a name="n12"></a><H2>14.5 Smobs</H2>
</a>
<p>
For pointer types, SWIG uses Guile smobs.
<p>
In earlier versions of SWIG, C pointers were represented as Scheme
strings containing a hexadecimal rendering of the pointer value and a
mangled type name. As Guile allows registering user types, so-called
"smobs" (small objects), a much cleaner representation has been
implemented now. The details will be discussed in the following.
<p>
A smob is a cons cell where the lower half of the CAR contains the
smob type tag, while the upper half of the CAR and the whole CDR are
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>#&lt;swig struct xyzzy * 0x1234affe&gt;</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_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.
<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.
<a name="n13"></a><H2>14.6 Exception Handling</H2>
</a>
<p>
SWIG code calls <code>scm_error</code> on exception, using the following
mapping:
<pre>
MAP(SWIG_MemoryError, "swig-memory-error");
MAP(SWIG_IOError, "swig-io-error");
MAP(SWIG_RuntimeError, "swig-runtime-error");
MAP(SWIG_IndexError, "swig-index-error");
MAP(SWIG_TypeError, "swig-type-error");
MAP(SWIG_DivisionByZero, "swig-division-by-zero");
MAP(SWIG_OverflowError, "swig-overflow-error");
MAP(SWIG_SyntaxError, "swig-syntax-error");
MAP(SWIG_ValueError, "swig-value-error");
MAP(SWIG_SystemError, "swig-system-error");
</pre>
<p>
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>
<p>If invoked with the command-line option <code>-procdoc
<var>file</var></code>, SWIG creates documentation strings for the
generated wrapper functions, describing the procedure signature and
return value, and writes them to <var>file</var>. You need Guile 1.4
or later to make use of the documentation files.
<p>SWIG can generate documentation strings in three formats, which are
selected via the command-line option <code>-procdocformat
<var>format</var></code>:
<ul>
<li><code>guile-1.4</code> (default): Generates a format suitable for Guile 1.4.
<li><code>plain</code>: Generates a format suitable for Guile 1.4.1 and
later.
<li><code>texinfo</code>: Generates texinfo source, which must be run
through texinfo in order to get a format suitable for Guile 1.4.1 and
later.
</ul>
<p>You need to register the generated documentation file with Guile
like this:
<pre>
(use-modules (ice-9 documentation))
(set! documentation-files
(cons "<var>file</var>" documentation-files))
</pre>
<p>Documentation strings can be configured using the Guile-specific
typemaps <code>indoc</code>, <code>outdoc</code>,
<code>argoutdoc</code>, <code>varindoc</code>, and
<code>varoutdoc</code>. See <code>Lib/guile/typemaps.i</code> for
details.
<a name="n15"></a><H2>14.8 Procedures with setters</H2>
</a>
<p>For global variables, SWIG creates a single wrapper procedure
<code>(<var>variable</var> :optional value)</code>, which is used for
both getting and setting the value. For struct members, SWIG creates
two wrapper procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer value)</code>.
<p>If invoked with the command-line option <code>-emit-setters</code>,
SWIG will additionally create procedures with setters. For global
variables, the procedure-with-setter <code><var>variable</var></code>
is created, so you can use <code>(<var>variable</var>)</code> to get
the value and <code>(set! (<var>variable</var>)
<var>value</var>)</code> to set it. For struct members, the
procedure-with-setter <code><var>struct</var>-<var>member</var></code>
is created, so you can use <code>(<var>struct</var>-<var>member</var>
<var>pointer</var>)</code> to get the value and <code>(set!
(<var>struct</var>-<var>member</var> <var>pointer</var>)
<var>value</var>)</code> to set it.
</body>
</html>

View File

@ -0,0 +1,392 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Introduction</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>1 Introduction</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">What is SWIG?</a>
<li><a href="#n3">Why use SWIG?</a>
<li><a href="#n4">A SWIG example</a>
<ul>
<li><a href="#n5">SWIG interface file</a>
<li><a href="#n6">The swig command</a>
<li><a href="#n7">Building a Perl5 module</a>
<li><a href="#n8">Building a Python module</a>
<li><a href="#n9">Shortcuts</a>
<li><a href="#n10">Building libraries and modules</a>
</ul>
<li><a href="#n11">Supported C/C++ language features</a>
<li><a href="#n12">Non-intrusive interface building</a>
<li><a href="#n13">Hands off code generation</a>
</ul>
<!-- INDEX -->
<a name="n2"></a><H2>1.1 What is SWIG?</H2>
SWIG is a software development tool that simplifies the task of
interfacing different languages to C and C++ programs. In a
nutshell, SWIG is a compiler that takes C declarations and creates
the wrappers needed to access those declarations from other languages including
including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally
requires no modifications to existing code and can often be used to
build a usable interface in only a few minutes. Possible applications
of SWIG include:
<p>
<ul>
<li>Building interpreted interfaces to existing C programs.
<li>Rapid prototyping and application development.
<li>Interactive debugging.
<li>Reengineering or refactoring of legacy software into a scripting language components.
<li>Making a graphical user interface (using Tk for example).
<li>Testing of C libraries and programs (using scripts).
<li>Building high performance C modules for scripting languages.
<li>Making C programming more enjoyable (or tolerable depending on your point of view)
<li>Impressing your friends.
<li>Obtaining vast sums of research funding (although obviously not applicable to the author).
</ul>
<p>
SWIG was originally designed to make it extremely easy for scientists
and engineers to build extensible scientific software without having to get a
degree in software engineering. Because of this, the use of
SWIG tends to be somewhat informal and ad-hoc (e.g., SWIG does not
require users to provide formal interface specifications as you would find in
a dedicated IDL compiler). Although
this style of development isn't appropriate for every
project, it is particularly well suited to software development in the
small; especially the research and development work that is commonly found
in scientific and engineering projects.
<a name="n3"></a><H2>1.2 Why use SWIG?</H2>
Although C is great for high-performance number crunching and systems
programming, trying to make an interactive and highly flexible C
program is a pain. Even though it is possible to build a user
interface using command line options, a home grown command
interpreter, or a graphical user interface, this often results in a
program that is hard to extend, hard to modify, hard to port between
platforms, and hard to use. Furthermore, this sort of activity wastes
a lot of development time because it usually diverts everyone's attention away
from the real problem that they're trying to solve.
<p>
Many of the problems with C are due to the way in which
many programs are organized. For example, a lot of programs
are structured as follows:
<p>
<ul>
<li>A collection of functions and variables that do something useful.
<li>A <tt>main()</tt> program that starts everything.
<li>A horrible collection of hacks that form some kind of user interface (but
which no-one really wants to touch).
</ul>
<p>
In this case, the <tt>main()</tt> program may read command line
options or simple commands from <tt>stdin</tt>. However, modifying or
extending the program to do something new requires changing the C
code, recompiling, and testing. If you make a mistake, you need to
repeat this cycle until things work. Of course, as more and more
features are added, the program usually turns into a horrible mess
that is even more difficult to modify than before (although this
undoubtedly increases the job security of the programmer).
<p>
A common mistake is to assume that all of the problems with C can somehow be
fixed by using a better C---perhaps an undebuggable
language with unreadable syntax, complicated semantics, and nearly
infinite compilation time. This is an unfortunate.
<P>
Perhaps a better approach is to place your application under the control
of a very high-level language such as a common scripting language
interpreter. High level languages excel at turning hard problems into
easy tasks. They also provide a nice framework for managing software components
and gluing different systems together. Not only that, they make it easy
for users to configure the software to their liking and to program it to perform
new tasks without ever having to touch a C/C++ compiler.
<p>
SWIG simplifies the task of incorporating C++ code into a high-level
programming environment. Specifically, rather than creating a huge
monolithic package, SWIG allows you to restructure your application as
a collection of functions and variables that can be accessed from the
convenience of a high-level language. With this model, all of the
functionality of your C program is retained. The only difference is
that the high-level program logic and control is now driven by the
high-level language instead of a low level
<tt>main()</tt> function.
<p>
SWIG tries to make the integration between scripting languages and C
as painless as possible. This allows you to focus on the underlying C
program and using the high-level scripting language interface, but not
the tedious and complex chore of making the two languages talk to each
other.<p>
<p>
<a name="n4"></a><H2>1.3 A SWIG example</H2>
The best way to illustrate SWIG is with a simple example. Consider the
following C code: <p>
<p>
<blockquote><pre>/* File : example.c */
double My_variable = 3.0;
/* Compute factorial of n */
int fact(int n) {
if (n &lt;= 1) return 1;
else return n*fact(n-1);
}
/* Compute n mod m */
int my_mod(int n, int m) {
return(n % m);
}
</pre></blockquote>
<p>
Suppose that you wanted to access these functions and the global
variable <tt>My_variable</tt> from Tcl. You start by making a SWIG
interface file as shown below (by convention, these files carry a .i
suffix) : <p>
<a name="n5"></a><H3>1.3.1 SWIG interface file</H3>
<blockquote><pre>
/* File : example.i */
%module example
%{
/* Put headers and other declarations here */
%}
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
</pre></blockquote>
<p>
The interface file contains ANSI C function prototypes and variable
declarations. The <tt>%module</tt> directive defines the name of the
module that will be created by SWIG. The <tt>%{,%}</tt> block
provides a location for inserting additional code such as C header
files or additional C declarations. <p>
<a name="n6"></a><H3>1.3.2 The swig command</H3>
SWIG is invoked using the <tt>swig</tt> command. We can use this to
build a Tcl module (under Linux) as follows :<p>
<p>
<blockquote><pre>unix &gt; <b>swig -tcl example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o example.so</b>
unix &gt; <b>tclsh</b>
% <b>load ./example.so</b>
% <b>fact 4</b>
24
% <b>my_mod 23 7</b>
2
% <b>expr $My_variable + 4.5</b>
7.5
%
</pre></blockquote>
<p>
The <tt>swig</tt> command produced a new file called
<tt>example_wrap.c</tt> that should be compiled along with the
<tt>example.c</tt> file. Most operating systems and scripting
languages now support dynamic loading of modules. In our example, our
Tcl module has been compiled into a shared library that can be loaded
into Tcl. When loaded, Tcl can now access the functions
and variables declared in the SWIG interface. A look at the file
<tt>example_wrap.c</tt> reveals a hideous mess. However, you
almost never need to worry about it.<p>
<a name="n7"></a><H3>1.3.3 Building a Perl5 module</H3>
Now, let's turn these functions into a Perl5 module. Without making
any changes type the following (shown for Solaris):<p>
<p>
<p>
<blockquote><pre>unix &gt; <b>swig -perl5 example.i</b>
unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix&gt; <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
unix &gt; <b>perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
&lt;ctrl-d&gt;</b>
24
2
7.5
unix &gt;
</pre></blockquote>
<a name="n8"></a><H3>1.3.4 Building a Python module</H3>
Finally, let's build a module for Python (shown for Irix).<p>
<p>
<blockquote><pre>unix &gt; <b>swig -python example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o _example.so</b>
unix &gt; <b>python</b>
Python 2.0 (#6, Feb 21 2001, 13:29:45)
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; <b>import example</b>
&gt;&gt;&gt; <b>example.fact(4)</b>
24
&gt;&gt;&gt; <b>example.my_mod(23,7)</b>
2
&gt;&gt;&gt; <b>example.cvar.My_variable + 4.5</b>
7.5
</pre></blockquote>
<a name="n9"></a><H3>1.3.5 Shortcuts</H3>
To the truly lazy programmer, one may wonder why we needed the extra
interface file at all. As it turns out, you can often do without
it. For example, you could also build a Perl5 module by just running
SWIG on the C header file and specifying a module name as follows<p>
<p>
<blockquote><pre>unix&gt; <b>swig -perl5 -module example example.h</b>
unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix&gt; <b>ld -G example.o example_wrap.o -o example.so</b>
unix &gt; <b>perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
&lt;ctrl-d&gt;</b>
24
2
7.5
</pre></blockquote>
<a name="n10"></a><H3>1.3.6 Building libraries and modules</H3>
In addition to generating wrapper code, SWIG provides extensive
support for handling multiple files and building interface
libraries. For example, our <tt>example.i</tt> file, could be used in
another interface as follows :<p>
<p>
<blockquote><pre>%module foo
%include example.i // Get definitions from example.i
... Now more declarations ...
</pre></blockquote>
In a large system, an interface might be built from a variety of pieces like this :<p>
<p>
<blockquote><pre>%module package
%include network.i
%include file.i
%include graphics.i
%include objects.i
%include simulation.i
</pre></blockquote>
SWIG comes with a library of existing functions known as the SWIG
library. The library contains a mix of language independent and
language dependent functionality. For example, the file
`<tt>array.i</tt>' provides access to C arrays while the file
`<tt>wish.i</tt>' includes specialized code for rebuilding the Tcl
wish interpreter. Using the library, you can use existing modules to
build up your own personalized environment for building interfaces.
If changes are made to any of the components, they will appear
automatically the next time SWIG is run. <p>
<a name="n11"></a><H2>1.4 Supported C/C++ language features</H2>
A primary goal of the SWIG project is to make the language binding
process extremely easy. Although a few simple examples have been shown,
SWIG is quite capable in supporting most of C++. Some of the
major features include:
<ul>
<li>Full C99 preprocessing.
<li>All ANSI C and C++ datatypes.
<li>Functions, variables, and constants.
<li>Classes.
<li>Single and multiple inheritance.
<li>Overloaded functions and methods.
<li>Overloaded operators.
<li>C++ templates (including member templates, specialization, and partial specialization).
<li>Namespaces.
<li>Variable length arguments.
<li>C++ smart pointers.
</ul>
Currently, the only C++ feature not supported is nested classes--a limitation
that will be removed in a future release.
<p>
It is important to stress that SWIG is not a simplistic C++ lexing
tool like several apparently similar wrapper generation tools. SWIG
not only parses C++, it implements the full C++ type system and it is
able to understand C++ semantics. SWIG generates its wrappers with
full knowledge of this information. As a result, you will find SWIG
to be just as capable of dealing with nasty corner cases as it is in
wrapping simple C++ code. In fact, SWIG is able handle C++ code that
stresses the very limits of many C++ compilers.
<a name="n12"></a><H2>1.5 Non-intrusive interface building</H2>
When used as intended, SWIG requires minimal modification to
existing C code. This makes SWIG extremely easy to use with existing
packages and promotes software reuse and modularity. By making
the C code independent of the high level interface, you can change the
interface and reuse the code in other applications. It is also
possible to support different types of interfaces depending on the application.
<a name="n13"></a><H2>1.6 Hands off code generation</H2>
SWIG is designed to produce working code that needs no
hand-modification (in fact, if you look at the output, you probably
won't want to modify it). Ideally, SWIG should be invoked
automatically inside a Makefile just as one would call the C
compiler. You should think of your scripting language interface being
defined entirely by the input to SWIG, not the resulting output
file. While this approach may limit flexibility for hard-core hackers,
it allows others to forget about the low-level implementation
details.
<p><hr>
<address>SWIG 1.3 - Last Modified : August 10, 2002</address>
</body>
</html>

3990
Doc/Manual/Java.html Normal file

File diff suppressed because it is too large Load Diff

1346
Doc/Manual/Library.html Normal file

File diff suppressed because it is too large Load Diff

522
Doc/Manual/Ocaml.html Normal file
View File

@ -0,0 +1,522 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Ocaml</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a>
<a name="n1"></a><H1>16 SWIG and Ocaml</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<ul>
<li><a href="#n3">Running SWIG</a>
<li><a href="#n4">Getting the right header files</a>
<li><a href="#n5">Compiling the code</a>
<li><a href="#n6">The camlp4 module</a>
<li><a href="#n7">Current thoughts on best practice for Ocaml</a>
<li><a href="#n8">Using your module</a>
<li><a href="#n9">Compilation problems and compiling with C++</a>
</ul>
<li><a href="#n10">The low-level Ocaml/C interface</a>
<ul>
<li><a href="#n11">The generated module</a>
<li><a href="#n12">Enums</a>
<li><a href="#n13">C++ Classes</a>
<ul>
<li><a href="#n14">C++ Class Example</a>
<li><a href="#n15">Compiling the example</a>
<li><a href="#n16">Sample Session</a>
</ul>
<li><a href="#n17">Exceptions</a>
</ul>
</ul>
<!-- INDEX -->
This chapter describes SWIG's
support of Ocaml. Ocaml is a relatively recent addition to the ML family,
and is a recent addition to SWIG. It's the second compiled, typed
language to be added. Ocaml has widely acknowledged benefits for engineers,
mostly derived from a sophistocated type system, compile-time checking
which eliminates several classes of common programming errors, and good
native performance. While all of this is wonderful, there are well-written
C and C++ libraries that Ocaml users will want to take advantage of as
part of their arsenal (such as SSL and gdbm), as well as their own mature
C and C++ code. SWIG allows this code to be used in a natural, type-safe
way with Ocaml, by providing the necessary, but repetetive glue code
which creates and uses Ocaml values to communicate with C and C++ code.
In addition, SWIG also produces the needed Ocaml source that binds
variants, functions, classes, etc.
<a name="n2"></a><H2>16.1 Preliminaries</H2>
SWIG 1.3 works with Ocaml 3.04 and above. Given the choice,
you should use the latest stable release. The SWIG Ocaml module has
been tested on Linux (m68k,MIPS,Intel) and Cygwin on Windows. The
best way to determine whether your system will work is to compile the
examples and test-suite which come with SWIG. You can do this by running
<tt>make check</tt> from the SWIG root directory after installing SWIG.
The Ocaml module has been tested using the system's dynamic linking (the
usual -lxxx against libxxx.so, but not using the explicit dynamic linking
provided by the Dl package <a
href="http://www.ocaml-programming.de/packages/documentation/dl/"> http://www.ocaml-programming.de/packages/documentation/dl/
</a>, although I suspect that it will work without a problem. If anyone
would like to evaluate this support, I will share the results here.
<a name="n3"></a><H3>16.1.1 Running SWIG</H3>
The basics of getting a SWIG Ocaml module up and running
can be seen from one of SWIG's example Makefiles, but is also described
here. To build an Ocaml module, run SWIG using the <tt>-ocaml</tt>
option.
<blockquote>
<pre>%swig -ocaml example.i</pre>
</blockquote>
<p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains
all of the C code needed to build an Ocaml module. To build the module,
you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
<tt>ocamlopt</tt> to create the needed .o file. You will need to compile
the resulting .ml and .mli files as well, and do the final link with -custom
(not needed for native link). </p>
<a name="n4"></a><H3>16.1.2 Getting the right header files</H3>
You may need the libswigocaml.h file that comes with the
distribution to be included. It provides several useful functions
that almost all programs that use SWIG will need. It is located in
$(prefix)/include/libswigocaml.h where $(prefix) is usually /usr/local,
but could be /usr. This is set at configure time. The functions most
frequently used in here are isnull and nullptr for creating and checking
null pointers.
<a name="n5"></a><H3>16.1.3 Compiling the code</H3>
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
SWIG interface like:
<p> </p>
<blockquote>
<pre>% ocamlc -c -ccopt "-I/usr/include/foo -I/usr/local/include" example_wrap.c<br>% ocamlc -c example.mli<br>% ocamlc -c example.ml<br></pre>
</blockquote>
<p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately,
it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked
in C++ mode, you must: </p>
<blockquote>
<pre>% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br></pre>
</blockquote>
<a name="n6"></a><H3>16.1.4 The camlp4 module</H3>
The camlp4 module (swig.ml -&gt; swig.cmo) contains a simple rewriter which
makes C++ code blend more seamlessly with objective caml code. It's use is
optional. The source file is included in the Lib/ocaml directory of the
SWIG source distribution.
<p>
The basic principle of the module is to recognize certain non-caml expressions
and convert them for use with C++ code as interfaced by SWIG. The camlp4
module is written to work with generated SWIG interfaces, and probably isn't
great to use with anything else.
<p>
Here are the main rewriting rules:
<p>
<table border="1">
<tr><th>Input</th><th>Rewritten to</th></tr>
<tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td>
<td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr>
<tr><td>object -> "method" ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td>
object <i>'binop</i> argument as in<br>
a '+= b</td>
<td>
(invoke object) "+=" argument as in<br>
(invoke a) "+=" b<td></tr>
<tr><th colspan=2>Note that because camlp4 always recognizes &lt;&lt;
and &gt;&gt;, they are replaced by lsl and lsr in operator names.
<tr><td>
<i>'unop</i> object as in</br>
'! a
</td><td>
(invoke a) "!" C_void</td></tr>
<tr><td>
<b>Smart pointer access like this</b>
object '-> "method" ( args )
</td><td>
(invoke (invoke object "->" C_void))
</td></tr>
<tr><td>
<b>Invoke syntax</b>
object . '( ... )
</td><td>
(invoke object) "()" (C_list [ ... ])
</td></tr>
<tr><td>
<b>Array syntax</b>
object '[ 10 ]
</td><td>
(invoke object) "[]" (C_int 10)
</td></tr>
</table>
<a name="n7"></a><H3>16.1.5 Current thoughts on best practice for Ocaml</H3>
Because the VC compiler (cl) needs link options specified
after all compiler options, and ocamlc doesn't really understand
that, I think that this is the best way to link ocaml code with C++
code. I formulated this method to make it easy for co-workers who
rely on MSDev to create GUIs, etc.. to live in harmony with the
ocaml parts of the application.
<p> Let's say you have ocaml sources foo.ml and bar.ml and interface frob.i;
</p>
<blockquote><pre>
swig -ocaml -c++ frob.i
ocamlc -custom -c frob.mli
ocamlc -custom -c frob.ml
cp frob_wrap.cxx frob_wrap.c
ocamlc -custom -c -I$(FROBLIB)/include frob_wrap.c
ocamlc -custom -c foo.ml
ocamlc -custom -c bar.ml
ocamlc -pack -o foobar.cmo foo.cmo bar.cmo frob.cmo
ocamlc -custom -output-obj -o foobar.obj foobar.cmo
</pre></blockquote>
<p> At this point, foobar.obj can be included in your MSVC project and
linked against other code. This is how you link it: </p>
<blockquote><pre>
link /OUT:big_program.exe \
other1.obj other2.obj foobar.obj frob_wrap.obj \
$(OCAMLLIB)/ocamlrun.lib $(FROBLIB)/lib/frob.lib
</pre></blockquote>
<a name="n8"></a><H3>16.1.6 Using your module</H3>
You can test-drive your module by building a
toplevel ocaml interpreter. Consult the ocaml manual for details.
<p>When linking any ocaml bytecode with your module, use the -custom
option to build your functions into the primitive list. This
option is not needed when you build native code.
<a name="n9"></a><H3>16.1.7 Compilation problems and compiling with C++</H3>
As mentioned above, .cxx files need special
handling to be compiled with <tt>ocamlc</tt>. Other than that, C code
that uses <tt>class</tt> as a non-keyword, and C code that is too
liberal with pointer types may not compile under the C++ compiler.
Most code meant to be compiled as C++ will not have problems.
<a name="n10"></a><H2>16.2 The low-level Ocaml/C interface</H2>
In order to provide access to overloaded functions, and
provide sensible outputs from them, all C entites are represented as
members of the c_obj type:
<p>
In the code as seen by the typemap
writer, there is a value, swig_result, that always contains the
current return data. It is a list, and must be appended with the
caml_list_append function, or with functions and macros provided by
objective caml.<br>
<blockquote><pre>
type c_obj =
C_void
| C_bool of bool
| C_char of char
| C_uchar of char
| C_short of int
| C_ushort of int
| C_int of int
| C_uint of int32
| C_int32 of int32
| C_int64 of int64
| C_float of float
| C_double of float
| C_ptr of int64 * int64
| C_array of c_obj array
| C_list of c_obj list
| C_obj of (string -&gt; c_obj -&gt; c_obj)
| C_string of string
| C_enum of c_enum_t
</pre></blockquote>
A few functions exist which generate and return these:<br>
<ul>
<li>caml_ptr_val receives a c_obj and returns a void *. &nbsp;This
should be used for all pointer purposes.</li>
<li>caml_long_val receives a c_obj and returns a long. &nbsp;This
should be used for most integral purposes.<br>
</li>
<li>caml_val_ptr receives a void * and returns a c_obj.</li>
<li>caml_val_bool receives a C int and returns a c_obj representing
it's bool value.</li>
<li>caml_val_(u)?(char|short|int|long|float|double) receives an
appropriate C value and returns a c_obj representing it.</li>
<li>caml_val_string receives a char * and returns a string value.</li>
<li>caml_val_string_len receives a char * and a length and returns
a string value.</li>
<li>caml_val_obj receives a void * and an object type and returns
a C_obj, which contains a closure giving method access.</li>
</ul>
Because of this style, a typemap can return any kind of value it
wants from a function. &nbsp;This enables out typemaps and inout typemaps
to work well. &nbsp;The one thing to remember about outputting values
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).<p>
&nbsp;This function will return a new list that has your element
appended. Upon return to caml space, the fnhelper function
beautifies the result. A list containing a single item degrades to
only that item (i.e. [ C_int 3 ] -&gt; C_int 3), and a list
containing more than one item is wrapped in C_list (i.e. [ C_char
'a' ; C_char 'b' -&gt; C_list [ C_char 'a' ; C_char b
]). &nbsp;This is in order to make return values easier to handle
when functions have only one return value, such as constructors,
and operators. &nbsp;In addition, string, pointer, and object
values are interchangable with respect to caml_ptr_val, so you can
allocate memory as caml strings and still use the resulting
pointers for C purposes, even using them to construct simple objects
on. Note, though, that foreign C++ code does not respect the garbage
collector, although the SWIG interface does.<p>
The wild card type that you can use in lots of different ways is
C_obj. It allows you to wrap any type of thing you like as an
object using the same mechanism that the ocaml module
does. &nbsp;When evaluated in caml_ptr_val, the returned value is
the result of a call to the object's "&" operator, taken as a pointer.
<p>
You should only construct values using objective caml, or using the
functions caml_val_* functions provided as static functions to a SWIG
ocaml module, as well as the caml_list_* functions. These functions
provide everything a typemap needs to produce values. In addition,
value items pass through directly, but you must make your own type
signature for a function that uses value in this way.
<a name="n11"></a><H3>16.2.1 The generated module</H3>
The SWIG <tt>%module</tt> directive specifies the name of the Ocaml
module to be generated. If you specified `<tt>%module example</tt>',
then your Ocaml code will be accessible in the module Example. The
module name is always capitalized as is the ocaml convention. Note
that you must not use any Ocaml keyword to name your module. Remember
that the keywords are not the same as the C++ ones. <p>
You can introduce extra code into the output wherever you like with SWIG.
These are the places you can introduce code:
<table border="1">
<tr><td>"header"</td><td>This code is inserted near the beginning of the
C wrapper file, before any function definitions.</td></tr>
<tr><td>"wrapper"</td><td>This code is inserted in the function definition
section.</td></tr>
<tr><td>"runtime"</td><td>This code is inserted near the end of the C wrapper
file.</td></tr>
<tr><td>"mli"</td><td>This code is inserted into the caml interface file.
Special signatures should be inserted here.
</td></tr>
<tr><td>"ml"</td><td>This code is inserted in the caml code defining the
interface to your C code. Special caml code, as well as any initialization
which should run when the module is loaded may be inserted here.
</td></tr>
</table>
<a name="n12"></a><H3>16.2.2 Enums</H3>
SWIG will wrap enumerations as polymorphic variants in the output
Ocaml code, as above in C_enum.&nbsp; In order to support all
C++-style uses of enums, the function int_to_enum and enum_to_int are
provided for ocaml code to produce and consume these values as
integers. &nbsp;Other than that, correct uses of enums will not have
a problem. &nbsp;Since enum labels may overlap between enums, the
enum_to_int and int_to_enum functions take an enum type label as an
argument. Example:
<p>
<blockquote><pre>
%module enum_test
%{
enum c_enum_type { a = 1, b, c = 4, d = 8 };
%}
enum c_enum_type { a = 1, b, c = 4, d = 8 };
</pre></blockquote>
<p>
The output mli contains:
<p>
<blockquote><pre>
type c_enum_type = [
`unknown
| `c_enum_type
]
type c_enum_tag = [
`int of int
| `a
| `b
| `c
| `d
]
val int_to_enum c_enum_type -&gt; int -&gt; c_obj
val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</pre>
</blockquote>
So it's possible to do this:
<blockquote>
<pre>bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
bash-2.05a$ ./enum_test_top
Objective Caml version 3.04
# open Enum_test ;;
# let x = C_enum `a ;;
val x : Enum_test.c_obj = C_enum `a
# enum_to_int `c_enum_type x ;;
- : Enum_test.c_obj = C_int 1
# int_to_enum `c_enum_type 4 ;;
- : Enum_test.c_obj = C_enum `c
</pre>
</blockquote>
<p> </p>
<a name="n13"></a><H3>16.2.3 C++ Classes</H3>
C++ classes, along with structs and unions are represented by C_obj
(string -&gt; c_obj -&gt; c_obj) wrapped closures. &nbsp;These objects
contain a method list, and a type, which allow them to be used like
C++ objects. When passed into typemaps that use pointers, they
degrade to pointers through their "&amp;" method. &nbsp;Every method
an object has is represented as a string in the object's method table,
and each method table exists in memory only once. &nbsp;In addition
to any other operators an object might have, certain builtin ones are
provided by SWIG: (all of these take no arguments (C_void))
<table>
<tr><td>"~"</td><td>Delete this object</td></tr>
<tr><td>"&amp;"</td><td>Return an ordinary C_ptr value representing this
object's address</td></tr>
<tr><td>":methods"</td><td>Returns a list of strings containing the names of
the methods this object contains</td></tr>
<tr><td>":classof"</td><td>Returns the name of the class this object belongs
to.</td></tr>
<tr><td>":parents"</td><td>Returns a list of all direct parent classes which
have been wrapped by SWIG.</td></tr>
<tr><td>"::[parent-class]"</td><td>Returns a view of the object as the
indicated parent class. This is mainly used internally by the SWIG module,
but may be useful to client programs.</td></tr>
<tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a
method with an optional parameter.
Called with one argument, the member variable is set to the value of the
argument. With zero arguments, the value is returned.
</td></tr>
</table>
Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object.
<p>
<a name="n14"></a><H4>16.2.3.1 C++ Class Example</H4>
Here's a simple example using Trolltech's Qt Library:
<table border="1" bgcolor="#dddddd"><tr><th><center>qt.i</center></th></tr>
<tr><td><pre>
%module qt
%{
#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;
%}
class QApplication {
public:
QApplication( int argc, char **argv );
void setMainWidget( QWidget *widget );
void exec();
};
class QPushButton {
public:
QPushButton( char *str, QWidget *w );
void resize( int x, int y );
void show();
};
</pre></td></tr></table><p>
<a name="n15"></a><H4>16.2.3.2 Compiling the example</H4>
<blockquote><pre>
bash-2.05a$ QTPATH=/your/qt/path
bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
bash-2.05a$ ocamlc -c qt.mli
bash-2.05a$ ocamlc -c qt.ml
bash-2.05a$ ocamlmktop -custom qt_wrap.o qt.cmo -o qt_top -cclib -L$QTPATH/lib -cclib -lqt
</pre></blockquote>
<a name="n16"></a><H4>16.2.3.3 Sample Session</H4>
<blockquote><pre>
bash-2.05a$ ./qt_top
Objective Caml version 3.06
# open Qt ;;
# let a = new_QApplication (C_list [ C_int 0; C_int 0 ]) ;;
val a : Qt.c_obj = C_obj <fun>
# let hello = new_QPushButton (C_list [ C_string "hi" ; C_int 0 ]) ;;
val hello : Qt.c_obj = C_obj <fun>
# (invoke hello) "resize" (C_list [ C_int 100 ; C_int 30 ]) ;;
- : Qt.c_obj = C_void
# (invoke hello) "show" C_void ;;
- : Qt.c_obj = C_void
# (invoke a) "exec" C_void ;;
</pre></blockquote><p>
Or with the camlp4 module:
<blockquote><pre>
bash-2.05a$ ./qt_top
Objective Caml version 3.06
# #load "camlp4o.cma" ;;
Camlp4 Parsing version 3.06
# #load "./swig.cmo" ;;
# open Qt ;;
# let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj <fun>
# let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj <fun>
# hello -> "resize" (100,30) ;;
- : Qt.c_obj = C_void
# hello -> "show" () ;;
- : Qt.c_obj = C_void
# a -> "exec" () ;;
</pre></blockquote><p>
In either case, assuming you have a working installation of QT, you will
see a window containing the string "hi" in a button.
<a name="n17"></a><H3>16.2.4 Exceptions</H3>
Catching exceptions is now supported using SWIG's %exception feature. A simple
but not too useful example is provided by the throw_exception testcase in
Examples/test-suite. You can provide your own exceptions, too.
</body>
</html>

2465
Doc/Manual/Perl5.html Normal file

File diff suppressed because it is too large Load Diff

496
Doc/Manual/Php.html Normal file
View File

@ -0,0 +1,496 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand crafted HTML -->
<html>
<head>
<title>SWIG and PHP4</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>18 SWIG and PHP4</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#n3">Building PHP4 Extensions</a>
<ul>
<li><a href="#n4">Building a loadable extension</a>
<li><a href="#n5">Basic PHP4 interface</a>
<li><a href="#n6">Functions</a>
<li><a href="#n7">Global Variables</a>
<li><a href="#n8">Pointers </a>
<li><a href="#n9">Structures and C++ classes</a>
<li><a href="#n10">Constants</a>
<li><a href="#n11">Shadow classes</a>
<li><a href="#n12">Constructors and Destructers</a>
<li><a href="#n13">Static Member Variables</a>
<li><a href="#n14">PHP4 Pragmas</a>
<li><a href="#n15">Building extensions into php</a>
<li><a href="#n16">To be furthered...</a>
</ul>
</ul>
<!-- INDEX -->
<b>Caution: This chapter (and module!) is still under construction</b>
In this chapter, we discuss SWIG's support of PHP4. The PHP4 module is
still under development so some of the features below may not work properly
(or at all!.)
<p>
The PHP4 module has undergone a lot of changes recently affecting the
way shadow classes are implemented so you should read this document even
if you thought you were familiar with what it said. The major change is
that shadow classes are implemented inside the php module in C++ instead
of in the generated .php file in php.
<a name="n2"></a><H2>18.1 Preliminaries</H2>
In order to use this module, you will need to have a copy of the PHP 4.0 (or
above) include files to compile the SWIG generated files. You can find these
files by running <tt>'php-config --includes'</tt>. To test the modules you will
need either the php binary or the Apache php module. If you want to build your
extension into php directly (without having the overhead of loading it into
each script), you will need the complete PHP source tree available.
<a name="n3"></a><H2>18.2 Building PHP4 Extensions</H2>
To build a PHP4 extension, run swig using the <tt>-php4</tt> option as follows :
<p>
<blockquote><pre>
swig -php4 example.i
</pre></blockquote>
This will produce 3 files by default. The first file, <tt>example_wrap.c</tt>
contains all of the C code needed to build a PHP4 extension. The second file,
<tt>php_example.h</tt> contains the header information needed to link the
extension into PHP. The third file, <tt>example.php</tt> can be included by
your php scripts. It will attempt to dynamically load your extension, and is
a place-holder for extra code specified in the interface file. If you want to
build your extension using the <tt>phpize</tt> utility, or if you want to
build your module into PHP directly, you can specify the <tt>-phpfull</tt>
command line argument to swig.
<p>
The <tt>-phpfull</tt> will generate three extra files.
The first extra file, <tt>config.m4</tt> contains the shell code needed to
enable the extension as part of the PHP4 build process. The second extra file,
<tt>Makefile.in</tt> contains the information needed to build the final
Makefile after substitutions. The third and final extra file, <tt>CREDITS</tt>
should contain the credits for the extension.
<p>
To finish building the extension, you have two choices. You can either build
the extension as a seperate object file which will then have to be explicitly
loaded by each script. Or you can rebuild the entire php source tree and build
the extension into the php executable/library so it will be available in every
script. The first choice is the default, however it can be changed by passing
the '-phpfull' command line switch to select the second build method.
<a name="n4"></a><H3>18.2.1 Building a loadable extension</H3>
To build a dynamic module for PHP, you have two options. You can use the
<tt>phpize</tt> utility, or you can do it manually.
<p>
To build manually, use a compile string similar to this (different for each
OS):
<blockquote><pre>
cc -I.. $(PHPINC) -fpic -c example_wrap.c
cc -shared example_wrap.o -o libexample.so
</pre></blockquote>
<p>
To build with phpize, after you have run swig you will need
to run the 'phpize' command (installed as part of php) in the same
directory. This re-creates the php build environment in that directory. It also
creates a configure file which includes the shell code from the config.m4 that
was generated by SWIG, this configure script will accept a command line argument
to enable the extension to be run ( by default the command line argument is
--enable-modulename, however you can edit the config.m4 file before running
phpize to accept --with-modulename. You can also add extra tests in config.m4
to check that a correct library version is installed or correct header files
are included, etc, but you must edit this file before running phpize. )
If you like SWIG can generate simple extra tests for libraries and header
files for you.
<blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote>
<p>
Will include in the config.m4 search for libxapian.a or libxapian.so and
search for libomquery.a or libomquery.so as well as a search for om.h
<p>
If you depend on source files not generated by SWIG, before generated
configure file, you may need to edit the <tt>
Makefile.in</tt> file. This contains the names of the source files to compile
(just the wrapper file by default) and any additional libraries needed to be
linked in. If there are extra C files to compile, you will need to add them
to the Makefile.in, or add the names of libraries if they are needed. In
simple cases SWIG is pretty good at generating a complete Makefile.in and
config.m4 which need no further editing. <p>
You then run the configure script with the command line argument needed
to enable the extension. Then run make, which builds the extension.
The extension object file will be left in the modules sub directory, you can
move it to wherever it is convenient to call from your php script.
<p>
<p>
To test the extension from a PHP script, you need to load it first. You do
this by putting the line,
<blockquote><pre>
dl("/path/to/modulename.so"); // Load the module
</pre></blockquote>
at the start of each PHP file. SWIG also generates a php module, which
attempts to do the <tt>dl()</tt> call for you:
<blockquote><pre>
include("example.php");
</pre></blockquote>
A more complicated method which builds the module directly into the <tt>php</tt>
executable is described <a href="n12">below</a>.
<a name="n5"></a><H3>18.2.2 Basic PHP4 interface</H3>
<a name="n6"></a><H3>18.2.3 Functions</H3>
C functions are converted into PHP functions. Default/optional arguments are
also allowed. An interface file like this :<p>
<p>
<blockquote><pre>%module default
int foo(int a);
double bar(double, double b = 3.0);
...
</pre></blockquote>
Will be accessed in PHP like this :<p>
<p>
<blockquote><pre>
dl("default.so"); $a = foo(2);
$b = bar(3.5, -1.5);
$c = bar(3.5); # Use default argument for 2nd parameter
</pre></blockquote>
<a name="n7"></a><H3>18.2.4 Global Variables</H3>
Global variables are difficult for PHP to handle, unlike Perl, their is no
'magic' way to intercept modifications made to variables, so changes in a PHP
variable will not be reflected in its C equivalent. To get around the problem,
two extra function are generated, <tt>Swig_sync_c()</tt> and <tt>Swig_sync_php()</tt>. These functions are called at the start and end of every function call,
ensuring changes made in PHP are updated in C ( and vice versa. ) Because this
is handled for you, you can modify the variables in PHP as normal, e.g.
<p><p>
<blockquote><pre>%module example;
...
double seki = 2;
...
int example_func(void);
</pre></blockquote>
is accessed as follow :<p>
<p>
<blockquote><pre>
dl("example.so");
print $seki;
$seki = $seki * 2; # Does not affect C variable, still equal to 2
example_func(); # Syncs C variable to PHP Variable, now both 4
<pre></blockquote>
SWIG supports global variables of all C datatypes including pointers and complex
objects.<p>
<a name="n8"></a><H3>18.2.5 Pointers </H3>
Pointers to C/C++ objects <b>no longer</b> represented as character
strings such as:<tt>_523d3f4_Circle_p</tt>, instead they are represented
as PHP resources, rather like MySQL connection handles.
<p>
You can also explicitly create a NULL pointer as a string "NULL"
or by passing a null or empty value.
<a name="n9"></a><H3>18.2.6 Structures and C++ classes</H3>
For structures and classes, SWIG produces accessor fuction for each member function and data. For example :<p>
<p>
<blockquote><pre>%module vector
class Vector {
public:
double x,y,z;
Vector();
~Vector();
double magnitude();
};
</pre></blockquote>
This gets turned into the following collection of PHP functions :<p>
<blockquote><pre>
Vector_x_set($obj);
Vector_x_get($obj);
Vector_y_set($obj);
Vector_y_get($obj);
Vector_z_set($obj);
Vector_z_get($obj);
new_Vector();
delete_Vector($obj);
Vector_magnitude($obj);
</pre></blockquote>
To use the class, simply use these functions. However, SWIG also has a mechanism
for creating shadow classes that hides these functions and uses an object
oriented interface instead - see <a href="n7">below</a>
<a name="n10"></a><H3>18.2.7 Constants</H3>
These work in much the same way as in C/C++, constants can be defined by using
either the normal C pre-processor declarations, or the <tt>%constant</tt> SWIG
directive. These will then be available from your PHP script as a PHP constant,
(e.g. no dollar sign is needed to access them. ) For example, with a swig file like this,
<p>
<blockquote><pre>
%module example
#define PI 3.14159
%constant int E = 2.71828
</pre>
</blockquote>
<p>
you can access from in your php script like this,
<blockquote><pre>
dl("libexample.so");
echo "PI = " . PI . "\n";
echo "E = " . E . "\n";
</pre>
</blockquote>
<p>
There are two peculiarities with using constants in PHP4. The first is that
if you try to use an undeclared constant, it will evaulate to a string
set to the constants name. For example,
<p>
<blockquote><pre>
%module example
#define EASY_TO_MISPELL 0
</pre>
</blockquote>
accessed incorrectly in PHP,
<p>
<blockquote>
<pre>
dl("libexample.so");
if(EASY_TO_MISPEL) {
....
} else {
....
}
</pre>
</blockquote>
<p>
will issue a warning about the undeclared constant, but will then evalute
it and turn it into a string ('EASY_TO_MISPEL'), which evaluates to true,
rather than the value of the constant which would be false. This is a feature.
<p>
The second 'feature' is that although constants are case sensitive (by default),
you cannot declare a constant twice with alternative cases. E.g.,
<p>
<blockquote>
<pre>
%module example
#define TEST Hello
#define Test World
</pre>
</blockquote>
accessed from PHP,
<p>
<pre>
<blockquote>
dl("libexample.so");
echo TEST, Test;
</blockquote>
</pre>
<p>
will output "Hello Test" rather than "Hello World". This is because internally,
all constants are stored in a hash table by their lower case name, so 'TEST' and
'Test' will map to the same hash element ('Test'). But, because we declared them case sensitive, the Zend engine will test if the case matches with the case the
constant was declared with first.
<p>
So, in the example above, the TEST constant was declared first, and will be stored under the hash element 'test'. The 'Test' constant will also map to the same hash element 'test', but will not overwrite it. When called from the script, the TEST constant will again be mapped to the hash element 'test' so the constant will be retrieved. The case will then be checked, and will match up, so the value ('Hello') will be returned. When 'Test' is evaulated, it will also map to the same hash element 'test'. The same constant will be retrieved, this time though the case check will fail as 'Test' != 'TEST'. So PHP will assume that Test is a undeclared constant, and as explained above, will return it as a string set to the constant name ('Test'). Hence the script above will print 'Hello Test'. If
they were declared non-case sensitive, the output would be 'Hello Hello', as
both point to the same value, without the case test taking place.
( Apologies, this paragraph needs rewritting to make some sense. )
</pre>
</blockquote>
<a name="n11"></a><H3>18.2.8 Shadow classes</H3>
To avoid having to call the various accessor function to get at structures or
class members, we can turn C structs and C++ classes into PHP classes that
can be be used directly in PHP scripts as objects and object methods. This is done by writing additional PHP code that builds PHP classes on top of the low-level SWIG interface. These PHP classes "shadow" an underlying C/C++ class.
To have SWIG create shadow classes, use the <tt>-shadow</tt> option :
<p><p><blockquote><pre>% swig -php4 -shadow tbc.i
</pre></blockquote>
<p>
This will produce the same files as before except that the final module
will declare internal PHP classes with the same names as the classes in
your .i file. No longer are the shadow classes defined in
the <tt>.php</tt> file, it will not contain significantly more support PHP
code.
For the most part, the code is the same except that we can now access members of
complex data structures using <tt>-&gt;</tt> instead of the low level access or
functions like before.
.... ( more examples on the way ) ....
<a name="n12"></a><H3>18.2.9 Constructors and Destructers</H3>
Constructors are used in PHP as in C++, they are called when the object is
created and any arguments are passed to them. However, function overloading
is not allowed in PHP so only one constructor can be used. This creates a
problem when copying objects, as we cannot avoid creating a whole new one
when all we want is to make it point to the same value as the original. This
is currently worked around by doing the following,
<ul>
<li>Create the new PHP object
<li>Delete the PHP objects pointer to the C object
<li>Set the PHP object's pointer to the same as the original PHP object's pointer.
</ul>
This is rather convoluted and hopefully will be improved upon in a later
release.
<p><p>
Because the internal wrapped objects are wrapped in PHP resources, PHP
handles the cleaning up when there are no more references to the wrapped
object. 'RegisterShutdownFunction' is no longer needed for this.
I am not sure if PHP resources are all freed at the end of a script, or
when they each go out of scope.
<a name="n13"></a><H3>18.2.10 Static Member Variables</H3>
Class variables are not supported in PHP, however class functions are, using
'::' syntax. Static member variables are therefore accessed using a class
function with the same name, which returns the current value of the class variable. For example
<blockquote><pre>
%module example
class Ko {
static int threats;
...
};
</pre></blockquote>
<p>
would be accessed in PHP as,
<blockquote><pre>
dl("libexample.so");
echo "There has now been " . Ko::threats() . " threats\n";
</pre></blockquote>
To set the static member variable, pass the value as the argument to the class function, e.g.
<blockquote><pre>
Ko::threats(10);
echo "There has now been " . Ko::threats() . " threats\n";
</pre></blockquote>
<a name="n14"></a><H3>18.2.11 PHP4 Pragmas</H3>
There are a few pragmas understood by the PHP4 module. The first,
<b>include</b> adds a file to be included by the generated PHP module. The
second, <b>code</b> adds literal code to the generated PHP module. The third,
<b>phpinfo</b> inserts code to the function called when PHP's phpinfo()
function is called.
<blockquote><pre>
/* example.i */
%pragma(php4) include="foo.php"
%pragma(php4) code="
function foo($bar) {
/* do something */
}
"
%pragma(php4) phpinfo="
zend_printf("An example of PHP support through SWIG\n");
php_info_print_table_start();
php_info_print_table_header(2, \"Directive\", \"Value\");
php_info_print_table_row(2, \"Example support\", \"enabled\");
php_info_print_table_end();
"
%include "example.h"
</pre></blockquote>
<a name="n15"></a><H3>18.2.12 Building extensions into php</H3>
This method, selected with the <tt>-phpfull</tt> command line switch, involves
rebuilding the entire php source tree. Whilst more complicated to build,
it does mean that the extension is then available without having to load it
in each script.
<p>
After running swig with the -phpfull switch, you will be left with a shockingly
similiar set of files to the previous build process. However you will then need
to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension ( e.g mkdir php-4.0.6/ext/modulename .)
<p>
After moving the files into this directory, you will need to run the 'buildall'
script in the php source directory. This rebuilds the configure script
and includes the extra command line arguments from the module you have added.
<p>
Before running the generated configure file, you may need to edit the <tt>
Makefile.in</tt>. This contains the names of the source files to compile (
just the wrapper file by default) and any additional libraries needed to
link in. If their are extra C files to compile you will need to add them
to the Makefile, or add the names of libraries if they are needed.
In most cases <tt>Makefile.in</tt> will be complete, especially if you
make use of <tt>-withlibs</tt> and <tt>-withincs</tt>
<blockquote><pre>
swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"
</pre></blockquote>
<p>
Will include in the config.m4 and Makefile.in search for libxapian.a or
libxapian.so and search for libomquery.a or libomquery.so as well as a
search for om.h
<p>
You then need to run the configure command and pass the necessary command
line arguments to enable your module ( by default this is --enable-modulename,
but this can be changed by editing the config.m4 file in the modules directory
before running the buildall script. In addition, extra tests can be added to
the config.m4 file to ensure the correct libraries and header files are
installed.)
<p>
Once configure has completed, you can run make to build php. If this all
compiles correctly, you should end up with a php executable/library
which contains your new module. You can test it with a php script which
does not have the 'dl' command as used above.
<a name="n16"></a><H3>18.2.13 To be furthered...</H3>
</body>
</html>

196
Doc/Manual/Preface.html Normal file
View File

@ -0,0 +1,196 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Preface</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>0 Preface</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">Special Introduction for Version 1.3</a>
<li><a href="#n4">SWIG Versions</a>
<li><a href="#n5">SWIG resources</a>
<li><a href="#n6">Prerequisites</a>
<li><a href="#n7">Organization of this manual</a>
<li><a href="#n8">How to avoid reading the manual</a>
<li><a href="#n9">Backwards Compatibility</a>
<li><a href="#n10">Credits</a>
<li><a href="#n11">Bug reports</a>
</ul>
<!-- INDEX -->
<a name="n2"></a><H2>0.1 Introduction</H2>
SWIG is a software development tool for building scripting language
interfaces to C and C++ programs. Originally developed in 1995, SWIG was
first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for
building user interfaces to simulation codes running on the Connection
Machine 5 supercomputer. In this environment, scientists needed to
work with huge amounts of simulation data, complex hardware, and a
constantly changing code base. The use of a scripting language
interface provided a simple yet highly flexible foundation for solving these
types of problems. SWIG simplifies development by largely automating
the task of scripting language integration--allowing developers and users
to focus on more important problems.
<p>
Although SWIG was originally developed for scientific applications, it
has since evolved into a general purpose tool that is used in a wide
variety of applications--in fact almost anything where C/C++ programming
is involved.
<p>
<a name="n3"></a><H2>0.2 Special Introduction for Version 1.3</H2>
Since SWIG was released in 1996, its user base and applicability has
continued to grow. Although its rate of development has varied, an
active development effort has continued to make improvements to the
system. Today, nearly a dozen developers are working to create
SWIG-2.0---a system that aims to provide wrapping support for nearly
all of the ANSI C++ standard and approximately ten target languages
including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby,
and Tcl.
<p>
<a name="n4"></a><H2>0.3 SWIG Versions</H2>
For several years, the most stable version of SWIG has been release
1.1p5. Starting with version 1.3, a new version numbering scheme has
been adopted. Odd version numbers (1.3, 1.5, etc.) represent
development versions of SWIG. Even version numbers (1.4, 1.6, etc.)
represent stable releases. Currently, developers are working to
create a stable SWIG-2.0 release (late 2002).
<a name="n5"></a><H2>0.4 SWIG resources</H2>
The official location of SWIG related material is<p>
<blockquote><pre>
<a href="http://www.swig.org">http://www.swig.org</a>
</pre></blockquote>
<p>
This site contains the latest version of the software, users guide,
and information regarding bugs, installation problems, and
implementation tricks.
<p>
You can also subscribe to the SWIG mailing list by visiting the page
<p>
<blockquote><pre><a href="http://mailman.cs.uchicago.edu/listinfo/swig">http://mailman.cs.uchicago.edu/listinfo/swig</a>
</pre></blockquote>
<p>
The mailing list often discusses some of the more technical aspects of
SWIG along with information about beta releases and future work.<p>
<p>
CVS access to the latest version of SWIG is also available. More information
about this can be obtained at:
<p>
<blockquote><pre><a href="http://www.swig.org/cvs.html">http://www.swig.org/cvs.html</a>
</pre></blockquote>
<a name="n6"></a><H2>0.5 Prerequisites</H2>
This manual assumes that you know how to write C/C++ programs and that you
have at least heard of scripting languages such as
Tcl, Python, and Perl. A detailed knowledge of these scripting
languages is not required although some familiarity won't
hurt. No prior experience with building C extensions to these
languages is required---after all, this is what SWIG does automatically.
However, you should be reasonably familiar with the use of
compilers, linkers, and makefiles since making
scripting language extensions is somewhat more complicated than
writing a normal C program.
<a name="n7"></a><H2>0.6 Organization of this manual</H2>
The first few chapters of this manual describe SWIG in general and
provide an overview of its capabilities. The remaining chapters are
devoted to specific SWIG language modules and are self
contained. Thus, if you are using SWIG to build Python interfaces, you
can probably skip to that chapter and find almost everything you need
to know. Caveat: we are currently working on a documentation rewrite and many
of the older language module chapters are still somewhat out of date.
<a name="n8"></a><H2>0.7 How to avoid reading the manual</H2>
If you hate reading manuals, glance at the "Introduction" which
contains a few simple examples. These
examples contain about 95% of everything you need to know to use
SWIG. After that, simply use the language-specific chapters as a reference.
The SWIG distribution also comes with a large directory of
examples that illustrate different topics.
<a name="n9"></a><H2>0.8 Backwards Compatibility</H2>
If you are a previous user of SWIG, don't expect recent versions of
SWIG to provide backwards compatibility. In fact, backwards
compatibility issues may arise even between successive 1.3.x releases.
Although these incompatibilities are regretable, SWIG-1.3 is an active
development project. The primary goal of this effort is to make SWIG
better---a process that would simply be impossible if the developers
are constantly bogged down with backwards compatibility issues.
<p>
On a positive note, a few incompatibilities are a small price to pay
for the large number of new features that have been
added---namespaces, templates, smart pointers, overloaded methods,
operators, and more.
<a name="n10"></a><H2>0.9 Credits</H2>
SWIG is an unfunded project that would not be possible without the
contributions of many people. Most recent SWIG development has been
supported by Matthias K&ouml;ppe, William Fulton, Lyle Johnson,
Richard Palmer, Thien-Thi Nguyen, Jason Stewart, Loic Dachary, Masaki
Fukushima, Luigi Ballabio, Sam Liddicott, Art Yerkes, Marcelo Matus, and Harco de Hilster.
<p>
Historically, the following people contributed to early versions of SWIG.
Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim Germann
at Los Alamos National Laboratory were the first users. Patrick
Tullmann at the University of Utah suggested the idea of automatic
documentation generation. John Schmidt and Kurtis Bleeker at the
University of Utah tested out the early versions. Chris Johnson
supported SWIG's developed at the University of Utah. John Buckman,
Larry Virden, and Tom Schwaller provided valuable input on the first
releases and improving the portability of SWIG. David Fletcher and
Gary Holt have provided a great deal of input on improving SWIG's
Perl5 implementation. Kevin Butler contributed the first Windows NT
port.
<a name="n11"></a><H2>0.10 Bug reports</H2>
Although every attempt has been made to make SWIG bug-free, we are also trying
to make feature improvements that may introduce bugs.
To report a bug, either send mail to the SWIG developer
list at <tt>swig-dev@cs.uchicago.edu</tt> or report a bug
at <tt>http://www.swig.org</tt>. In your report, be as specific as
possible, including (if applicable), error messages, tracebacks (if a
core dump occurred), corresponding portions of the SWIG interface file
used, and any important pieces of the SWIG generated wrapper code. We
can only fix bugs if we know about them.
<p><hr>
<address>SWIG 1.3 - Last Modified : August 10, 2002</address>
</body>
</html>

View File

@ -0,0 +1,302 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG Preprocessor</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>6 Preprocessing</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">File inclusion</a>
<li><a href="#n3">File imports</a>
<li><a href="#n4">Conditional Compilation</a>
<li><a href="#n5">Macro Expansion</a>
<li><a href="#n6">SWIG Macros</a>
<li><a href="#n7">C99 Extensions</a>
<li><a href="#n8">Preprocessing and %{ ... %} blocks</a>
<li><a href="#n9">Preprocessing and { ... }</a>
</ul>
<!-- INDEX -->
SWIG includes its own enhanced version of the C preprocessor. The preprocessor
supports the standard preprocessor directives and macro expansion rules.
However, a number of modifications and enhancements have been made. This
chapter describes some of these modifications.
<a name="n2"></a><H2>6.1 File inclusion</H2>
To include another file into a SWIG interface, use the <tt>%include</tt> directive
like this:
<blockquote>
<pre>
%include "pointer.i"
</pre>
</blockquote>
Unlike, <tt>#include</tt>, <tt>%include</tt> includes each file once (and will not
reload the file on subsequent <tt>%include</tt> declarations). Therefore, it
is not necessary to use include-guards in SWIG interfaces.
<p>
By default, the <tt>#include</tt> is ignored unless you run SWIG with the
<tt>-includeall</tt> option. The reason for ignoring traditional includes
is that you often don't want SWIG to try and wrap everything included
in standard header system headers and auxilliary files.
<a name="n3"></a><H2>6.2 File imports</H2>
SWIG provides another file inclusion directive with the <tt>%import</tt> directive.
For example:
<blockquote>
<pre>
%import "foo.i"
</pre>
</blockquote>
The purpose of <tt>%import</tt> is to collect certain information from another
SWIG interface file or a header file without actually generating any wrapper code.
Such information generally includes type declarations (e.g., <tt>typedef</tt>) as well as
C++ classes that might be used as base-classes for class declarations in the interface.
The use of <tt>%import</tt> is also important when SWIG is used to generate
extensions as a collection of related modules. This is advanced topic and is described
in a later chapter.
<P>
The <tt>-importall</tt> directive tells SWIG to follow all <tt>#include</tt> statements
as imports. This might be useful if you want to extract type definitions from system
header files without generating any wrappers.
<a name="n4"></a><H2>6.3 Conditional Compilation</H2>
SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
include parts of an interface. The following symbols are predefined
by SWIG when it is parsing the interface:
<p>
<blockquote><pre>
SWIG Always defined when SWIG is processing a file
SWIGTCL Defined when using Tcl
SWIGTCL8 Defined when using Tcl8.0
SWIGPERL Defined when using Perl
SWIGPERL5 Defined when using Perl5
SWIGPYTHON Defined when using Python
SWIGGUILE Defined when using Guile
SWIGRUBY Defined when using Ruby
SWIGJAVA Defined when using Java
SWIGMZSCHEME Defined when using Mzscheme
SWIGWIN Defined when running SWIG under Windows
SWIGMAC Defined when running SWIG on the Macintosh
</pre></blockquote>
In addition, SWIG defines the following set of standard C/C++ macros:
<blockquote>
<pre>
__LINE__ Current line number
__FILE__ Current file name
__STDC__ Defined to indicate ANSI C
__cplusplus Defined when -c++ option used
</pre>
</blockquote>
Interface files can look at these symbols as necessary to change the
way in which an interface is generated or to mix SWIG directives with
C code. These symbols are also defined within the C code generated by
SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
within the SWIG compiler).<p>
<a name="n5"></a><H2>6.4 Macro Expansion</H2>
Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the <tt>#define</tt> statement
is also used to try and detect constants. Therefore, if you have something like this in your file,
<blockquote>
<pre>
#ifndef _FOO_H 1
#define _FOO_H 1
...
#endif
</pre>
</blockquote>
you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface.
<p>
More complex macros can be defined in the standard way. For example:
<blockquote>
<pre>
#define EXTERN extern
#ifdef __STDC__
#define _ANSI(args) (args)
#else
#define _ANSI(args) ()
#endif
</pre>
</blockquote>
The following operators can appear in macro definitions:
<ul>
<li><tt>#x</tt><br>
Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x").
<p>
<li><tt>x ## y</tt><br>
Concatenates x and y together to form <tt>xy</tt>.
<p>
<li><tt>`x`</tt><br>
If <tt>x</tt> is a string surrounded by double quotes, do nothing. Otherwise, turn into a string
like <tt>#x</tt>. This is a non-standard SWIG extension.
</ul>
<a name="n6"></a><H2>6.5 SWIG Macros</H2>
SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives.
For example:
<blockquote>
<pre>
%define ARRAYHELPER(type,name)
%inline %{
type *new_ ## name (int nitems) {
return (type *) malloc(sizeof(type)*nitems);
}
void delete_ ## name(type *t) {
free(t);
}
type name ## _get(type *t, int index) {
return t[index];
}
void name ## _set(type *t, int index, type val) {
t[index] = val;
}
%}
%enddef
ARRAYHELPER(int, IntArray)
ARRAYHELPER(double, DoubleArray)
</pre>
</blockquote>
The primary purpose of <tt>%define</tt> is to define large macros of code. Unlike normal C preprocessor
macros, it is not necessary to terminate each line with a continuation character (\)--the macro definition
extends to the first occurrence of <tt>%enddef</tt>. Furthermore, when such macros are expanded,
they are reparsed through the C preprocessor. Thus, SWIG macros can contain all other preprocessor
directives except for nested <tt>%define</tt> statements.
<p>
The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact,
many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template
support).
<a name="n7"></a><H2>6.6 C99 Extensions</H2>
SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
<blockquote>
<pre>
#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__)
</pre>
</blockquote>
When used, any extra arguments to <tt>...</tt> are placed into the
special variable <tt>__VA_ARGS__</tt>. This also works with special SWIG
macros defined using <tt>%define</tt>.
<p>
SWIG allows a variable number of arguments to be empty. However, this often results
in an extra comma (,) and syntax error in the resulting expansion. For example:
<blockquote>
<pre>
DEBUGF("hello"); --> fprintf(stderr,"hello",);
</pre>
</blockquote>
To get rid of the extra comma, use <tt>##</tt> like this:
<blockquote>
<pre>
#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__)
</pre>
</blockquote>
<b>Comment:</b> It's not entirely clear how variadic macros might be useful to
interface building. However, they are used internally to implement a number of
SWIG directives and are provided to make SWIG more compatible with C99 code.
<a name="n8"></a><H2>6.7 Preprocessing and %{ ... %} blocks</H2>
The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore,
if you write code like this,
<blockquote>
<pre>
%{
#ifdef NEED_BLAH
int blah() {
...
}
#endif
%}
</pre>
</blockquote>
the contents of the <tt>%{ ... %}</tt> block are copied without
modification to the output (including all preprocessor directives).
<a name="n9"></a><H2>6.8 Preprocessing and { ... }</H2>
SWIG always runs the preprocessor on text appearing inside <tt>{ ... }</tt>. However,
sometimes it is desirable to make a preprocessor directive pass through to the output
file. For example:
<blockquote>
<pre>
%extend Foo {
void bar() {
#ifdef DEBUG
printf("I'm in bar\n");
#endif
}
}
</pre>
</blockquote>
By default, SWIG will interpret the <tt>#ifdef DEBUG</tt> statement. However, if you really wanted that code
to actually go into the wrapper file, prefix the preprocessor directives with <tt>%</tt> like this:
<blockquote>
<pre>
%extend Foo {
void bar() {
%#ifdef DEBUG
printf("I'm in bar\n");
%#endif
}
}
</pre>
</blockquote>
SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code.
<p><hr>
<address>SWIG 1.3 - Last Modified : May 25, 2002</address>
</body>
</html>

3311
Doc/Manual/Python.html Normal file

File diff suppressed because it is too large Load Diff

6
Doc/Manual/README Normal file
View File

@ -0,0 +1,6 @@
This directory contains the HTML for the SWIG users manual.
All of this HTML is hand-written. However, section numbering, indices,
and the table of contents is generated automatically by the 'maketoc.py'
script.

3007
Doc/Manual/Ruby.html Normal file

File diff suppressed because it is too large Load Diff

2631
Doc/Manual/SWIG.html Normal file

File diff suppressed because it is too large Load Diff

3408
Doc/Manual/SWIGPlus.html Normal file

File diff suppressed because it is too large Load Diff

439
Doc/Manual/Scripting.html Normal file
View File

@ -0,0 +1,439 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Scripting Languages</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>3 Scripting Languages</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">The two language view of the world</a>
<li><a href="#n3">How does a scripting language talk to C?</a>
<ul>
<li><a href="#n4">Wrapper functions</a>
<li><a href="#n5">Variable linking</a>
<li><a href="#n6">Constants</a>
<li><a href="#n7">Structures and classes</a>
<li><a href="#n8">Shadow classes</a>
</ul>
<li><a href="#n9">Building scripting language extensions</a>
<ul>
<li><a href="#n10">Shared libraries and dynamic loading</a>
<li><a href="#n11">Linking with shared libraries</a>
<li><a href="#n12">Static linking</a>
</ul>
</ul>
<!-- INDEX -->
This chapter provides a brief overview of scripting language extension
programming and the mechanisms by which scripting language interpreters
access C and C++ code.
<a name="n2"></a><H2>3.1 The two language view of the world</H2>
When a scripting language is used to control a C program, the
resulting system tends to look as follows:
<p><center><img src="ch2.1.png"></center><p>
<p>
<p>
In this programming model, the scripting language interpreter is used
for high level control whereas the underlying functionality of the
C/C++ program is accessed through special scripting language
"commands." If you have ever tried to write your own simple command
interpreter, you might view the scripting language approach
to be a highly advanced implementation of that. Likewise,
If you have ever used a package such as MATLAB or IDL, it is a
very similar model--the interpreter executes user commands and
scripts. However, most of the underlying functionality is written in
a low-level language like C or Fortran.
<p>
The two-language model of computing is extremely powerful because it
exploits the strengths of each language. C/C++ can be used for maximal
performance and complicated systems programming tasks. Scripting
languages can be used for rapid prototyping, interactive debugging,
scripting, and access to high-level data structures such associative
arrays. <p>
<a name="n3"></a><H2>3.2 How does a scripting language talk to C?</H2>
Scripting languages are built around a parser that knows how
to execute commands and scripts. Within this parser, there is a
mechanism for executing commands and accessing variables.
Normally, this is used to implement the builtin features
of the language. However, by extending the interpreter, it is usually
possible to add new commands and variables. To do this,
most languages define a special API for adding new commands.
Furthermore, a special foreign function interface defines how these
new commands are supposed to hook into the interpreter.
<p>
Typically, when you add a new command to a scripting interpreter
you need to do two things; first you need to write a special
"wrapper" function that serves as the glue between the interpreter
and the underlying C function. Then you need to give the interpreter
information about the wrapper by providing details about the name of the
function, arguments, and so forth. The next few sections illustrate
the process.
<a name="n4"></a><H3>3.2.1 Wrapper functions</H3>
Suppose you have an ordinary C function like this :<p>
<p>
<blockquote><pre>int fact(int n) {
if (n &lt;= 1) return 1;
else return n*fact(n-1);
}
</pre></blockquote>
<p>
In order to access this function from a scripting language, it is
necessary to write a special "wrapper" function that serves as the
glue between the scripting language and the underlying C function. A
wrapper function must do three things :<p>
<p>
<ul>
<li>Gather function arguments and make sure they are valid.
<li>Call the C function.
<li>Convert the return value into a form recognized by the scripting language.
</ul>
<p>
As an example, the Tcl wrapper function for the <tt>fact()</tt>
function above example might look like the following : <p>
<blockquote><pre>
int wrap_fact(ClientData clientData, Tcl_Interp *interp,
int argc, char *argv[]) {
int result;
int arg0;
if (argc != 2) {
interp-&gt;result = "wrong # args";
return TCL_ERROR;
}
arg0 = atoi(argv[1]);
result = fact(arg0);
sprintf(interp-&gt;result,"%d", result);
return TCL_OK;
}
</pre></blockquote>
Once you have created a wrapper function, the final step is to tell the
scripting language about the new function. This is usually done in an
initialization function called by the language when the module is
loaded. For example, adding the above function to the Tcl interpreter
requires code like the following :<p>
<p>
<blockquote><pre>int Wrap_Init(Tcl_Interp *interp) {
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
</pre></blockquote>
<p>
When executed, Tcl will now have a new command called "<tt>fact</tt>"
that you can use like any other Tcl command.<p>
<p>
Although the process of adding a new function to Tcl has been
illustrated, the procedure is almost identical for Perl and
Python. Both require special wrappers to be written and both need
additional initialization code. Only the specific details are
different.<p>
<a name="n5"></a><H3>3.2.2 Variable linking</H3>
Variable linking refers to the problem of mapping a
C/C++ global variable to a variable in the scripting
language interpeter. For example, suppose you had the following
variable:<p>
<p>
<blockquote><pre>double Foo = 3.5;
</pre></blockquote>
<p>
It might be nice to access it from a script as follows (shown for Perl):<p>
<p>
<blockquote><pre>$a = $Foo * 2.3; # Evaluation
$Foo = $a + 2.0; # Assignment
</pre></blockquote>
<p>
To provide such access, variables are commonly manipulated using a
pair of get/set functions. For example, whenever the value of a
variable is read, a "get" function is invoked. Similarly, whenever
the value of a variable is changed, a "set" function is called.
<p>
In many languages, calls to the get/set functions can be attached to
evaluation and assignment operators. Therefore, evaluating a variable
such as <tt>$Foo</tt> might implicitly call the get function. Similarly,
typing <tt>$Foo = 4</tt> would call the underlying set function to change
the value.
<a name="n6"></a><H3>3.2.3 Constants</H3>
In many cases, a C program or library may define a large collection of
constants. For example:
<blockquote><pre>#define RED 0xff0000
#define BLUE 0x0000ff
#define GREEN 0x00ff00
</pre></blockquote>
To make constants available, their values can be stored in scripting
language variables such as <tt>$RED</tt>, <tt>$BLUE</tt>, and
<tt>$GREEN</tt>. Virtually all scripting languages provide C
functions for creating variables so installing constants is usually
a trivial exercise.
<a name="n7"></a><H3>3.2.4 Structures and classes</H3>
Although scripting languages have no trouble accessing simple
functions and variables, accessing C/C++ structures and classes
present a different problem. This is because the implementation
of structures is largely related to the problem of
data representation and layout. Furthermore, certain language features
are difficult to map to an interpreter. For instance, what
does C++ inheritance mean in a Perl interface?
<p>
The most straightforward technique for handling structures is to
implement a collection of accessor functions that hide the underlying
representation of a structure. For example,
<p>
<blockquote><pre>struct Vector {
Vector();
~Vector();
double x,y,z;
};
</pre></blockquote>
can be transformed into the following set of functions :<p>
<p>
<blockquote><pre>Vector *new_Vector();
void delete_Vector(Vector *v);
double Vector_x_get(Vector *v);
double Vector_y_get(Vector *v);
double Vector_y_get(Vector *v);
void Vector_x_set(Vector *v, double x);
void Vector_y_set(Vector *v, double y);
void Vector_z_set(Vector *v, double z);
</pre></blockquote>
Now, from an interpreter these function might be used as follows:
<p>
<blockquote><pre>% set v [new_Vector]
% Vector_x_set $v 3.5
% Vector_y_get $v
% delete_Vector $v
% ...
</pre></blockquote>
<p>
Since accessor functions provide a mechanism for accessing the
internals of an object, the interpreter does not need to know anything
about the actual representation of a <tt>Vector</tt>.
<a name="n8"></a><H3>3.2.5 Shadow classes</H3>
In certain cases, it is possible to use the low-level accessor functions
to create something known as a "shadow" class.
A "shadow class" is a special kind of object that gets created
in a scripting language to access a C/C++ class (or struct) in a way
that looks like the original structure (that is, it "shadows" the real
C++ class). For example, if you
have the following C definition :<p>
<blockquote><pre>
class Vector {
public:
Vector();
~Vector();
double x,y,z;
};
</pre></blockquote>
<p>
A shadow classing mechanism would allow you to access the structure in
a more natural manner from the interpreter. For example, in Python, you might want to do this:
<p>
<blockquote><pre>&gt;&gt;&gt; v = Vector()
&gt;&gt;&gt; v.x = 3
&gt;&gt;&gt; v.y = 4
&gt;&gt;&gt; v.z = -13
&gt;&gt;&gt; ...
&gt;&gt;&gt; del v
</pre></blockquote>
<p>
Similarly, in Perl5 you may want the interface to work like this:<p>
<blockquote><pre>
$v = new Vector;
$v-&gt;{x} = 3;
$v-&gt;{y} = 4;
$v-&gt;{z} = -13;
</pre></blockquote>
Finally, in Tcl :<p>
<blockquote><pre>
Vector v
v configure -x 3 -y 4 -z 13
</pre></blockquote>
When shadow classes are used, two objects are at really work--one in
the scripting language, and an underlying C/C++ object. Operations
affect both objects equally and for all practical purposes, it appears
as if you are simply manipulating a C/C++ object.
<a name="n9"></a><H2>3.3 Building scripting language extensions</H2>
The final step in using a scripting language with your C/C++
application is adding your extensions to the scripting language
itself. There are two primary approaches for doing
this. The preferred technique is to build a dynamically loadable
extension in the form a shared library. Alternatively, you can
recompile the scripting language interpreter with your extensions
added to it.
<a name="n10"></a><H3>3.3.1 Shared libraries and dynamic loading</H3>
To create a shared library or DLL, you often need to look at the
manual pages for your compiler and linker. However, the procedure
for a few common machines is shown below:<p>
<p>
<blockquote><pre># Build a shared library for Solaris
gcc -c example.c example_wrap.c -I/usr/local/include
ld -G example.o example_wrap.o -o example.so
# Build a shared library for Linux
agcc -fpic -c example.c example_wrap.c -I/usr/local/include
gcc -shared example.o example_wrap.o -o example.so
# Build a shared library for Irix
gcc -c example.c example_wrap.c -I/usr/local/include
ld -shared example.o example_wrap.o -o example.so
</pre></blockquote>
To use your shared library, you simply use the corresponding command
in the scripting language (load, import, use, etc...). This will
import your module and allow you to start using it. For example:
<p>
<blockquote><pre>% load ./example.so
% fact 4
24
%
</pre></blockquote>
<p>
When working with C++ codes, the process of building shared libraries
may be more complicated--primarily due to the fact that C++ modules may need
additional code in order to operate correctly. On many machines, you
can build a shared C++ module by following the above procedures, but
changing the link line to the following :<p>
<p>
<blockquote><pre>c++ -shared example.o example_wrap.o -o example.so
</pre></blockquote>
<p>
<a name="n11"></a><H3>3.3.2 Linking with shared libraries</H3>
When building extensions as shared libraries, it is not uncommon for
your extension to rely upon other shared libraries on your machine. In
order for the extension to work, it needs to be able to find all of
these libraries at run-time. Otherwise, you may get an error such as
the following :<p>
<p>
<blockquote><pre>&gt;&gt;&gt; import graph
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ?
File "/home/sci/data1/beazley/graph/graph.py", line 2, in ?
import graphc
ImportError: 1101:/home/sci/data1/beazley/bin/python: rld: Fatal Error: cannot
successfully map soname 'libgraph.so' under any of the filenames /usr/lib/libgraph.so:/
lib/libgraph.so:/lib/cmplrs/cc/libgraph.so:/usr/lib/cmplrs/cc/libgraph.so:
&gt;&gt;&gt;
</pre></blockquote>
<p>
What this error means is that the extension module created by SWIG
depends upon a shared library called "<tt>libgraph.so</tt>" that the
system was unable to locate. To fix this problem, there are a few
approaches you can take.<p>
<p>
<ul>
<li>Link your extension and explicitly tell the linker where the
required libraries are located. Often times, this can be done with a
special linker flag such as <tt>-R</tt>, <tt>-rpath</tt>, etc. This
is not implemented in a standard manner so read the man pages for your
linker to find out more about how to set the search path for shared
libraries.
<li>Put shared libraries in the same directory as the executable. This
technique is sometimes required for correct operation on non-Unix
platforms.
<li>Set the UNIX environment variable <tt>LD_LIBRARY_PATH</tt> to the
directory where shared libraries are located before running Python.
Although this is an easy solution, it is not recommended. Consider setting
the path using linker options instead.
</ul>
<a name="n12"></a><H3>3.3.3 Static linking</H3>
With static linking, you rebuild the scripting language interpreter
with extensions. The process usually involves compiling a short main
program that adds your customized commands to the language and starts
the interpreter. You then link your program with a library to produce
a new scripting language executable.
<p>
Although static linking is supported on all platforms, this is not
the preferred technique for building scripting language
extensions. In fact, there are very few practical reasons for doing this--consider
using shared libraries instead.
<p><hr>
<address>SWIG 1.3 - Last Modified : July 16, 2001</address>
</body>
</html>

2930
Doc/Manual/Tcl.html Normal file

File diff suppressed because it is too large Load Diff

2764
Doc/Manual/Typemaps.html Normal file

File diff suppressed because it is too large Load Diff

831
Doc/Manual/Varargs.html Normal file
View File

@ -0,0 +1,831 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Variable Length Arguments</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>10 Variable Length Arguments</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">The Problem</a>
<li><a href="#n4">Default varargs support</a>
<li><a href="#n5">Argument replacement using %varargs</a>
<li><a href="#n6">Varargs and typemaps</a>
<li><a href="#n7">Varargs wrapping with libffi</a>
<li><a href="#n8">Wrapping of va_list</a>
<li><a href="#n9">C++ Issues</a>
<li><a href="#n10">Discussion</a>
</ul>
<!-- INDEX -->
<b>(a.k.a, "The horror. The horror.")</b>
<p>
This chapter describes the problem of wrapping functions that take a
variable number of arguments. For instance, generating wrappers for
the C <tt>printf()</tt> family of functions.
<p>
This topic is sufficiently advanced to merit its own chapter. In
fact, support for varargs is an often requested feature that was first
added in SWIG-1.3.12. Most other wrapper generation tools have
wisely chosen to avoid this issue.
<a name="n2"></a><H2>10.1 Introduction</H2>
Some C and C++ programs may include functions that accept a variable
number of arguments. For example, most programmers are
familiar with functions from the C library such as the following:
<blockquote>
<pre>
int printf(const char *fmt, ...)
int fprintf(FILE *, const char *fmt, ...);
int sprintf(char *s, const char *fmt, ...);
</pre>
</blockquote>
Although there is probably little practical purpose in wrapping these
specific C library functions in a scripting language (what would be the
point?), a library may include its own set of special functions based
on a similar API. For example:
<blockquote>
<pre>
int traceprintf(const char *fmt, ...);
</pre>
</blockquote>
In this case, you may want to have some kind of access from the target language.
<p>
Before describing the SWIG implementation, it is important to discuss
the common uses of varargs that you are likely to encounter in real
programs. Obviously, there are the <tt>printf()</tt> style output
functions as shown. Closely related to this would be
<tt>scanf()</tt> style input functions that accept a format string and a
list of pointers into which return values are placed. However, variable
length arguments are also sometimes used to write functions that accept a
NULL-terminated list of pointers. A good example of this would
be a function like this:
<blockquote>
<pre>
int execlp(const char *path, const char *arg1, ...);
...
/* Example */
execlp("ls","ls","-l",NULL);
</pre>
</blockquote>
In addition, varargs is sometimes used to fake default arguments in older
C libraries. For instance, the low level <tt>open()</tt> system call
is often declared as a varargs function so that it will accept two
or three arguments:
<blockquote>
<pre>
int open(const char *path, int oflag, ...);
...
/* Examples */
f = open("foo", O_RDONLY);
g = open("bar", O_WRONLY | O_CREAT, 0644);
</pre>
</blockquote>
Finally, to implement a varargs function, recall that you have to use
the C library functions defined in <tt>&lt;stdarg.h&gt;</tt>. For
example:
<blockquote>
<pre>
List make_list(const char *s, ...) {
va_list ap;
List *x = new List();
...
va_start(ap, s);
while (s) {
x.append(s);
s = va_arg(ap, const char *);
}
va_end(ap);
return x;
}
</pre>
</blockquote>
<a name="n3"></a><H2>10.2 The Problem</H2>
Generating wrappers for a variable length argument function presents a
number of special challenges. Although C provides support for
implementing functions that receive variable length arguments, there
are no functions that can go in the other direction. Specifically,
you can't write a function that dynamically creates a list of
arguments and which invokes a varargs function on your behalf.
<p>
Although it is possible to write functions that accept the special
type <tt>va_list</tt>, this is something entirely different. You
can't take a <tt>va_list</tt> structure and pass it in place of the
variable length arguments to another varargs function. It just
doesn't work.
<p>
The reason this doesn't work has to do with the way that function
calls get compiled. For example, suppose that your program has a function call like this:
<blockquote>
<pre>
printf("Hello %s. Your number is %d\n", name, num);
</pre>
</blockquote>
When the compiler looks at this, it knows that you are calling
<tt>printf()</tt> with exactly three arguments. Furthermore, it knows
that the number of arguments as well are their types and sizes is
<em>never</em> going to change during program execution. Therefore,
this gets turned to machine code that sets up a three-argument stack
frame followed by a call to <tt>printf()</tt>.
<p>
In contrast, suppose you attempted to make some kind of wrapper around
<tt>printf()</tt> using code like this:
<blockquote>
<pre>
int wrap_printf(const char *fmt, ...) {
va_list ap;
va_start(ap,fmt);
...
printf(fmt,ap);
...
va_end(ap);
};
</blockquote>
</pre>
Athough this code might compile, it won't do what you expect. This is
because the call to <tt>printf()</tt> is compiled as a procedure call
involving only two arguments. However, clearly a two-argument
configuration of the call stack is completely wrong if your intent is
to pass an arbitrary number of arguments to the real
<tt>printf()</tt>. Needless to say, it won't work.
<p>
Unfortunately, the situation just described is exactly the problem
faced by wrapper generation tools. In general, the number of passed
arguments will not be known until run-time. To make matters even
worse, you won't know the types and sizes of arguments until run-time
as well. Needless to say, there is no obvious way to make the C
compiler generate code for a function call involving an unknown number
of arguments of unknown types.
<p>
In theory, it <em>is</em> possible to write a wrapper that does the right thing.
However, this involves knowing the underlying ABI for the target platform and language
as well as writing special purpose code that manually constructed the call stack before
making a procedure call. Unfortunately, both of these tasks require the use of inline
assembly code. Clearly, that's the kind of solution you would much rather avoid.
<p>
With this nastiness in mind, SWIG provides a number of solutions to the varargs
wrapping problem. Most of these solutions are compromises that provide limited
varargs support without having to resort to assembly language. However, SWIG
can also support real varargs wrapping (with stack-frame manipulation) if you
are willing to get hands dirty. Keep reading.
<a name="n4"></a><H2>10.3 Default varargs support</H2>
When variable length arguments appear in an interface, the default
behavior is to drop the variable argument list entirely, replacing
them with a single NULL pointer. For example, if you had this
function,
<blockquote>
<pre>
void traceprintf(const char *fmt, ...);
</pre>
</blockquote>
it would be wrapped as if it had been declared as follows:
<blockquote>
<pre>
void traceprintf(const char *fmt);
</pre>
</blockquote>
When the function is called inside the wrappers, it is called as follows:
<blockquote>
<pre>
traceprintf(arg1, NULL);
</pre>
</blockquote>
Arguably, this approach seems to defeat the whole point of variable length arguments. However,
this actually provides enough support for many simple kinds of varargs functions to still be useful. For
instance, you could make function calls like this (in Python):
<blockquote>
<pre>
>>> traceprintf("Hello World")
>>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
</pre>
</blockquote>
Notice how string formatting is being done in Python instead of C.
<a name="n5"></a><H2>10.4 Argument replacement using %varargs</H2>
Instead of dropping the variable length arguments, an alternative approach is to replace
<tt>(...)</tt> with a set of suitable arguments. SWIG provides a special <tt>%varargs</tt> directive
that can be used to do this. For example,
<blockquote>
<pre>
%varargs(int mode = 0) open;
...
int open(const char *path, int oflags, ...);
</pre>
</blockquote>
is equivalent to this:
<blockquote>
<pre>
int open(const char *path, int oflags, int mode = 0);
</pre>
</blockquote>
In this case, <tt>%varargs</tt> is simply providing more specific information about the
extra arguments that might be passed to a function.
If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also
accept a numerical argument count as follows:
<blockquote>
<pre>
%varargs(10,char *arg = NULL) execlp;
...
int execlp(const char *path, const char *arg1, ...);
</pre>
</blockquote>
This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments.
Depending on the application, this may be more than enough for practical purposes.
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments is uniform and the maximum number of arguments is
known. When replicated argument replacement is used, at least one extra
argument is added to the end of the arguments when making the function call.
This argument serves as a sentinel to make sure the list is properly terminated.
It has the same value as that supplied to the <tt>%varargs</tt> directive.
<p>
Argument replacement is not as useful when working with functions that accept
mixed argument types such as <tt>printf()</tt>. Providing general purpose
wrappers to such functions presents special problems (covered shortly).
<a name="n6"></a><H2>10.5 Varargs and typemaps</H2>
Variable length arguments may be used in typemap specifications. For example:
<blockquote>
<pre>
%typemap(in) (...) {
// Get variable length arguments (somehow)
...
}
%typemap(in) (const char *fmt, ...) {
// Multi-argument typemap
}
</pre>
</blockquote>
However, this immediately raises the question of what "type" is actually used
to represent <tt>(...)</tt>. For lack of a better alternative, the type of
<tt>(...)</tt> is set to <tt>void *</tt>. Since there is no
way to dynamically pass arguments to a varargs function (as previously described),
the <tt>void *</tt> argument value is intended to serve as a place holder
for storing some kind of information about the extra arguments (if any). In addition, the
default behavior of SWIG is to pass the <tt>void *</tt> value as an argument to
the function. Therefore, you could use the pointer to hold a valid argument value if you wanted.
<p>
To illustrate, here is a safer version of wrapping <tt>printf()</tt> in Python:
<blockquote>
<pre>
%typemap(in) (const char *fmt, ...) {
$1 = "%s"; /* Fix format string to %s */
$2 = (void *) PyString_AsString($input); /* Get string argument */
};
...
int printf(const char *fmt, ...);
</pre>
</blockquote>
In this example, the format string is implicitly set to <tt>"%s"</tt>.
This prevents a program from passing a bogus format string to the
extension. Then, the passed input object is decoded and placed in the
<tt>void *</tt> argument defined for the <tt>(...)</tt> argument. When the
actual function call is made, the underlying wrapper code will look roughly
like this:
<blockquote>
<pre>
wrap_printf() {
char *arg1;
void *arg2;
int result;
arg1 = "%s";
arg2 = (void *) PyString_AsString(arg2obj);
...
result = printf(arg1,arg2);
...
}
</pre>
</blockquote>
Notice how both arguments are passed to the function and it does what you
would expect.
<p>
The next example illustrates a more advanced kind of varargs typemap.
Disclaimer: this requires special support in the target language module and is not
guaranteed to work with all SWIG modules at this time. It also starts to illustrate
some of the more fundamental problems with supporting varargs in more generality.
<p>
If a typemap is defined for any form of <tt>(...)</tt>, many SWIG
modules will generate wrappers that accept a variable number of
arguments as input and will make these arguments available in some
form. The precise details of this depends on the language module
being used (consult the appropriate chapter for more details).
However, suppose that you wanted to create a Python wrapper for the
<tt>execlp()</tt> function shown earlier. To do this using a typemap
instead of using <tt>%varargs</tt>, you might first write a typemap
like this:
<blockquote>
<pre>
%typemap(in) (...)(char *args[10]) {
int i;
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc > 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments");
return NULL;
}
for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
return NULL;
}
args[i] = PyString_AsString(o);
}
$1 = (void *) args;
}
</pre>
</blockquote>
In this typemap, the special variable <tt>varargs</tt> is a tuple
holding all of the extra arguments passed (this is specific to the
Python module). The typemap then pulls this apart and sticks the
values into the array of strings <tt>args</tt>. Then, the array is
assigned to <tt>$1</tt> (recall that this is the <tt>void *</tt>
variable corresponding to <tt>(...)</tt>). However, this assignment
is only half of the picture----clearly this alone is not enough to
make the function work. To patch everything up, you have to rewrite the
underlying action code using the <tt>%feature</tt> directive like
this:
<blockquote>
<pre>
%feature("action") execlp {
char *args = (char **) arg3;
result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
args[5],args[6],args[7],args[8],args[9], NULL);
}
int execlp(const char *path, const char *arg, ...);
</pre>
</blockquote>
<p>
This patches everything up and creates a function that more or less
works. However, don't try explaining this to your coworkers unless
you know for certain that they've had several cups of coffee. If you
really want to elevate your guru status and increase your job
security, continue to the next section.
<a name="n7"></a><H2>10.6 Varargs wrapping with libffi</H2>
All of the previous examples have relied on features of SWIG that are
portable and which don't rely upon any low-level machine-level
details. In many ways, they have all dodged the real issue of variable
length arguments by recasting a varargs function into some weaker variation
with a fixed number of arguments of known types. In many cases, this
works perfectly fine. However, if you want more generality than this,
you need to bring out some bigger guns.
<P>
One way to do this is to use a special purpose library such as libffi
(<a
href="http://sources.redhat.com/libffi/">http://sources.redhat.com/libffi</a>).
libffi is a library that allows you to dynamically construct
call-stacks and invoke procedures in a relatively platform independent
manner. Details about the library can be found in the libffi
distribution and are not repeated here.
<p>
To illustrate the use of libffi, suppose that you <em>really</em> wanted to create a
wrapper for <tt>execlp()</tt> that accepted <em>any</em> number of
arguments. To do this, you might make a few adjustments to the previous
example. For example:
<blockquote>
<pre>
/* Take an arbitrary number of extra arguments and place into an array
of strings */
%typemap(in) (...) {
char **argv;
int argc;
int i;
argc = PyTuple_Size(varargs);
argv = (char **) malloc(sizeof(char *)*(argc+1));
for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
free(argv);
return NULL;
}
argv[i] = PyString_AsString(o);
}
argv[i] = NULL;
$1 = (void *) argv;
}
/* Rewrite the function call, using libffi */
%feature("action") execlp {
int i, vc;
ffi_cif cif;
ffi_type **types;
void **values;
char **args;
vc = PyTuple_Size(varargs);
types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
values = (void **) malloc((vc+3)*sizeof(void *));
args = (char **) arg3;
/* Set up path parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
/* Set up first argument */
types[1] = &ffi_type_pointer;
values[1] = &arg2;
/* Set up rest of parameters */
for (i = 0; i &lt;= vc; i++) {
types[2+i] = &ffi_type_pointer;
values[2+i] = &args[i];
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) execlp, &result, values);
} else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types);
free(values);
free(arg3);
return NULL;
}
free(types);
free(values);
free(arg3);
}
/* Declare the function. Whew! */
int execlp(const char *path, const char *arg1, ...);
</pre>
</blockquote>
Looking at this example, you may start to wonder if SWIG is making
life any easier. Given the amount of code involved, you might also wonder
why you didn't just write a hand-crafted wrapper! Either that or you're wondering
"why in the hell am I trying to wrap this varargs function in the
first place?!?" Obviously, those are questions you'll have to answer for yourself.
<p>
As a more extreme example of libffi, here is some code that attempts to wrap <tt>printf()</tt>,
<blockquote>
<pre>
/* A wrapper for printf() using libffi */
%{
/* Structure for holding passed arguments after conversion */
typedef struct {
int type;
union {
int ivalue;
double dvalue;
void *pvalue;
} val;
} vtype;
enum { VT_INT, VT_DOUBLE, VT_POINTER };
%}
%typemap(in) (const char *fmt, ...) {
vtype *argv;
int argc;
int i;
/* Format string */
$1 = PyString_AsString($input);
/* Variable length arguments */
argc = PyTuple_Size(varargs);
argv = (vtype *) malloc(argc*sizeof(vtype));
for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (PyInt_Check(o)) {
argv[i].type = VT_INT;
argv[i].val.ivalue = PyInt_AsLong(o);
} else if (PyFloat_Check(o)) {
argv[i].type = VT_DOUBLE;
argv[i].val.dvalue = PyFloat_AsDouble(o);
} else if (PyString_Check(o)) {
argv[i].type = VT_POINTER;
argv[i].val.pvalue = (void *) PyString_AsString(o);
} else {
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
free(argv);
return NULL;
}
}
$2 = (void *) argv;
}
/* Rewrite the function call using libffi */
%feature("action") printf {
int i, vc;
ffi_cif cif;
ffi_type **types;
void **values;
vtype *args;
vc = PyTuple_Size(varargs);
types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
values = (void **) malloc((vc+1)*sizeof(void *));
args = (vtype *) arg2;
/* Set up fmt parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
/* Set up rest of parameters */
for (i = 0; i &lt; vc; i++) {
switch(args[i].type) {
case VT_INT:
types[1+i] = &ffi_type_uint;
values[1+i] = &args[i].val.ivalue;
break;
case VT_DOUBLE:
types[1+i] = &ffi_type_double;
values[1+i] = &args[i].val.dvalue;
break;
case VT_POINTER:
types[1+i] = &ffi_type_pointer;
values[1+i] = &args[i].val.pvalue;
break;
default:
abort(); /* Whoa! We're seriously hosed */
break;
}
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) printf, &result, values);
} else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types);
free(values);
free(args);
return NULL;
}
free(types);
free(values);
free(args);
}
/* The function */
int printf(const char *fmt, ...);
</pre>
</blockquote>
Much to your amazement, it even seems to work if you try it:
<blockquote>
<pre>
>>> import example
>>> example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60)
Grade: Dave 47/60 = 78.33%
>>>
</pre>
</blockquote>
Of course, there are still some limitations to consider:
<blockquote>
<pre>
>>> example.printf("la de da de da %s", 42)
Segmentation fault (core dumped)
</pre>
</blockquote>
And, on this note, we leave further exploration of libffi to the reader as an exercise. Although Python has been used as an example,
most of the techniques in this section can be extrapolated to other language modules with a bit of work. The only
details you need to know is how the extra arguments are accessed in each target language. For example, in the Python
module, we used the special <tt>varargs</tt> variable to get these arguments. Modules such as Tcl8 and Perl5 simply
provide an argument number for the first extra argument. This can be used to index into an array of passed arguments to get
values. Please consult the chapter on each language module for more details.
<a name="n8"></a><H2>10.7 Wrapping of va_list</H2>
Closely related to variable length argument wrapping, you may encounter functions that accept a parameter
of type <tt>va_list</tt>. For example:
<blockquote>
<pre>
int vfprintf(FILE *f, const char *fmt, va_list ap);
</pre>
</blockquote>
As far as we know, there is no obvious way to wrap these functions
with SWIG. This is because there is no documented way to assemble the
proper va_list structure (there are no C library functions to do it
and the contents of va_list are opaque). Not only that, the contents
of a <tt>va_list</tt> structure are closely tied to the underlying
call-stack. It's not clear that exporting a <tt>va_list</tt> would
have any use or that it would work at all.
<a name="n9"></a><H2>10.8 C++ Issues</H2>
Wrapping of C++ member functions that accept a variable number of
arguments presents a number of challenges. By far, the easiest way to
handle this is to use the <tt>%varargs</tt> directive. This is portable
and it fully supports classes much like the <tt>%rename</tt> directive. For example:
<blockquote>
<pre>
%varargs (10, char * = NULL) Foo::bar;
class Foo {
public:
virtual void bar(char *arg, ...); // gets varargs above
};
class Spam: public Foo {
public:
virtual void bar(char *arg, ...); // gets varargs above
};
</pre>
</blockquote>
<tt>%varargs</tt> also works with constructors, operators, and any
other C++ programming construct that accepts variable arguments.
<p>
Doing anything more advanced than this is likely to involve a serious
world of pain. In order to use a library like libffi, you will need
to know the underlying calling conventions and details of the C++ ABI. For
instance, the details of how <tt>this</tt> is passed to member
functions as well as any hidden arguments that might be used to pass
additional information. These details are implementation specific and
may differ between compilers and even different versions of the same
compiler. Also, be aware that invoking a member function is further
complicated if it is a virtual method. In this case,
invocation might require a table lookup to obtain the proper function address
(although you might be able to obtain an address by casting a bound
pointer to a pointer to function as described in the C++ ARM section
18.3.4).
<p>
If you do decide to change the underlying action code, be aware that SWIG
always places the <tt>this</tt> pointer in <tt>arg1</tt>. Other arguments
are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example:
<blockquote>
<pre>
%feature("action") Foo::bar {
...
result = arg1->bar(arg2, arg3, etc.);
...
}
</pre>
</blockquote>
Given the potential to shoot yourself in the foot, it is probably easier to reconsider your
design or to provide an alternative interface using a helper function than it is to create a
fully general wrapper to a varargs C++ member function.
<a name="n10"></a><H2>10.9 Discussion</H2>
This chapter has provided a number of techniques that can be used to address the problem of variable length
argument wrapping. If you care about portability and ease of use, the <tt>%varargs</tt> directive is
probably the easiest way to tackle the problem. However, using typemaps, it is possible to do some very advanced
kinds of wrapping.
<p>
One point of discussion concerns the structure of the libffi examples in the previous section. Looking
at that code, it is not at all clear that this is the easiest way to solve the problem. However, there
are a number of subtle aspects of the solution to consider--mostly concerning the way in which the
problem has been decomposed. First, the example is structured in a way that tries to maintain separation
between wrapper-specific information and the declaration of the function itself. The idea here is that
you might structure your interface like this:
<blockquote>
<pre>
%typemap(const char *fmt, ...) {
...
}
%feature("action") traceprintf {
...
}
/* Include some header file with traceprintf in it */
%include "someheader.h"
</pre>
</blockquote>
Second, careful scrutiny will reveal that the typemaps involving <tt>(...)</tt> have nothing
whatsoever to do with the libffi library. In fact, they are generic with respect to the way in which
the function is actually called. This decoupling means that it will be much easier to consider
other library alternatives for making the function call. For instance, if libffi wasn't supported on a certain
platform, you might be able to use something else instead. You could use conditional compilation
to control this:
<blockquote>
<pre>
#ifdef USE_LIBFFI
%feature("action") printf {
...
}
#endif
#ifdef USE_OTHERFFI
%feature("action") printf {
...
}
#endif
</pre>
</blockquote>
Finally, even though you might be inclined to just write a hand-written wrapper for varargs functions,
the techniques used in the previous section have the advantage of being compatible with all other features
of SWIG such as exception handling.
<p>
As a final word, some C programmers seem to have the assumption that
the wrapping of variable length argument functions is an easily solved
problem. However, this section has hopefully dispelled some of these
myths. All things being equal, you are better off avoiding variable
length arguments if you can. If you can't avoid them, please consider
some of the simple solutions first. If you can't live with a simple
solution, proceed with caution. At the very least, make sure you
carefully read the section "A7.3.2 Function Calls" in Kernighan and
Ritchie and make sure you fully understand the parameter passing conventions used for varargs.
Also, be aware of the platform dependencies and reliability issues that
this will introduce. Good luck.
<p><hr>
<address>SWIG 1.3 - Last Modified : March 24, 2002</address>
</body>
</html>

401
Doc/Manual/Warnings.html Normal file
View File

@ -0,0 +1,401 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Warning Messages</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>11 Warning Messages</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Introduction</a>
<li><a href="#n3">Warning message suppression</a>
<li><a href="#n4">Enabling additional warnings</a>
<li><a href="#n5">Issuing a warning message</a>
<li><a href="#n6">Commentary</a>
<li><a href="#n7">Warning number reference</a>
<ul>
<li><a href="#n8">Deprecated features (100-199)</a>
<li><a href="#n9">Preprocessor (200-299)</a>
<li><a href="#n10">C/C++ Parser (300-399)</a>
<li><a href="#n11">Types and typemaps (400-499) </a>
<li><a href="#n12">Code generation (500-599)</a>
<li><a href="#n13">Language module specific (800-899) </a>
<li><a href="#n14">User defined (900-999)</a>
</ul>
<li><a href="#n15">History</a>
</ul>
<!-- INDEX -->
<a name="n2"></a><H2>11.1 Introduction</H2>
During compilation, SWIG may generate a variety of warning messages. For example:
<blockquote>
<pre>
example.i:16: Warning(501): Overloaded declaration ignored. bar(double)
example.i:15: Warning(501): Previous declaration is bar(int)
</pre>
</blockquote>
Typically, warning messages indicate non-fatal problems with the input
where the generated wrapper code will probably compile, but it may not
work like you expect.
<a name="n3"></a><H2>11.2 Warning message suppression</H2>
All warning messages have a numeric code that is shown in the warning message itself.
To suppress the printing of a warning message, a number of techniques can be used.
First, you can run SWIG with the <tt>-w</tt> command line option. For example:
<blockquote>
<pre>
% swig -python -w501 example.i
% swig -python -w501,505,401 example.i
</pre>
</blockquote>
Alternatively, warnings can be suppressed by inserting a special preprocessor pragma
into the input file:
<blockquote>
<pre>
%module example
#pragma SWIG nowarn=501
#pragma SWIG nowarn=501,505,401
</pre>
</blockquote>
Finally, code-generation warnings can be disabled on a declaration by declaration basis using
the <tt>%warnfilter</tt> directive. For example:
<blockquote>
<pre>
%module example
%warnfilter(501) foo;
...
int foo(int);
int foo(double); // Silently ignored.
</pre>
</blockquote>
The <tt>%warnfilter</tt> directive has the same semantics as other declaration modifiers like
<tt>%rename</tt>, <tt>%ignore</tt>, and <tt>%feature</tt>. For example, if you wanted to
suppress a warning for a method in a class hierarchy, you could do this:
<blockquote>
<pre>
%warnfilter(501) Object::foo;
class Object {
public:
int foo(int);
int foo(double); // Silently ignored
...
};
class Derived : public Object {
public:
int foo(int);
int foo(double); // Silently ignored
...
};
</pre>
</blockquote>
Warnings can be suppressed for an entire class by supplying a class name. For example:
<blockquote>
<pre>
%warnfilter(501) Object;
class Object {
public:
... // All 501 warnings ignored in class
};
</pre>
</blockquote>
There is no option to suppress all SWIG warning messages. The warning messages are there
for a reason---to tell you that something may be <em>broken</em> in
your interface. Ignore the warning messages at your own peril.
<a name="n4"></a><H2>11.3 Enabling additional warnings</H2>
Some warning messages are disabled by default and are generated only
to provide additional diagnostics. All warning messages can be
enabled using the <tt>-Wall</tt> option. For example:
<blockquote>
<pre>
% swig -Wall -python example.i
</pre>
</blockquote>
When <tt>-Wall</tt> is used, all other warning filters are disabled.
<p>
To selectively turn on extra warning messages, you can use the directives and options in the
previous section--simply add a "+" to all warning numbers. For example:
<blockquote>
<pre>
% swig -w+309,+452 example.i
</pre>
</blockquote>
or
<blockquote>
<pre>
#pragma SWIG nowarn=+309,+452
</pre>
</blockquote>
or
<blockquote>
<pre>
%warnfilter(+309,+452) foo;
</pre>
</blockquote>
Note: selective enabling of warnings with <tt>%warnfilter</tt> overrides any global settings you might have
made using <tt>-w</tt> or <tt>#pragma</tt>.
<a name="n5"></a><H2>11.4 Issuing a warning message</H2>
Warning messages can be issued from an interface file using a number of directives. The
<tt>%warn</tt> directive is the most simple:
<blockquote>
<pre>
%warn "750:This is your last warning!"
</pre>
</blockquote>
All warning messages are optionally prefixed by the warning number to use. If you are generating
your own warnings, make sure you don't use numbers defined in the table at the end of this section.
<p>
The <tt>%ignorewarn</tt> directive is the same as <tt>%ignore</tt> except that it issues a
warning message whenever a matching declaration is found. For example:
<blockquote>
<pre>
%ignorewarn("362:operator= ignored") operator=;
</pre>
</blockquote>
Warning messages can be associated with typemaps using the
<tt>warning</tt> attribute of a typemap declaration. For example:
<blockquote>
<pre>
%typemap(in, warning="751:You are really going to regret this") blah * {
...
}
</pre>
</blockquote>
In this case, the warning message will be printed whenever the typemap is actually used.
<a name="n6"></a><H2>11.5 Commentary</H2>
The ability to suppress warning messages is really only provided for
advanced users and is not recommended in normal use. There are no
plans to provide symbolic names or options that identify specific
types or groups of warning messages---the numbers must be used
explicitly.
<p>
Certain types of SWIG problems are errors. These usually arise due to
parsing errors (bad syntax) or semantic problems for which there is
no obvious recovery. There is no mechanism for suppressing error
messages or handling errors as warnings---you must make changes to
the input file to fix the problem.
<a name="n7"></a><H2>11.6 Warning number reference</H2>
<a name="n8"></a><H3>11.6.1 Deprecated features (100-199)</H3>
<ul>
<li>101. Deprecated <tt>%extern</tt> directive.
<li>102. Deprecated <tt>%val</tt> directive.
<li>103. Deprecated <tt>%out</tt> directive.
<li>104. Deprecated <tt>%disabledoc</tt> directive.
<li>105. Deprecated <tt>%enabledoc</tt> directive.
<li>106. Deprecated <tt>%doconly</tt> directive.
<li>107. Deprecated <tt>%style</tt> directive.
<li>108. Deprecated <tt>%localstyle</tt> directive.
<li>109. Deprecated <tt>%title</tt> directive.
<li>110. Deprecated <tt>%section</tt> directive.
<li>111. Deprecated <tt>%subsection</tt> directive.
<li>112. Deprecated <tt>%subsubsection</tt> directive.
<li>113. Deprecated <tt>%addmethods</tt> directive.
<li>114. Deprecated <tt>%readonly</tt> directive.
<li>115. Deprecated <tt>%readwrite</tt> directive.
<li>116. Deprecated <tt>%except</tt> directive.
<li>117. Deprecated <tt>%new</tt> directive.
<li>118. Deprecated <tt>%typemap(except)</tt>.
</ul>
<a name="n9"></a><H3>11.6.2 Preprocessor (200-299)</H3>
<ul>
<li>201. Unable to find 'filename'.
<li>202. Could not evaluate 'expr'.
</ul>
<a name="n10"></a><H3>11.6.3 C/C++ Parser (300-399)</H3>
<ul>
<li>301. <tt>class</tt> keyword used, but not in C++ mode.
<li>302. Identifier '<em>name</em>' redeclared (ignored).
<li>303. <tt>%extend</tt> defined for an undeclared class '<em>name</em>'.
<li>304. Unsupported constant value (ignored).
<li>305. Bad constant value (ignored).
<li>306. '<em>identifier</em>' is private in this context.
<li>307. Can't set default argument value (ignored)
<li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>'
<li>309. [private | protected] inheritance ignored.
<li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored)
<li>311. Template partial specialization not supported.
<li>312. Nested classes not currently supported (ignored).
<li>313. Unrecognized extern type "<em>name</em>" (ignored).
<li>314. '<em>identifier</em>' is a <em>lang</em> keyword.
<li>315. Nothing known about '<em>identifier</em>'.
<li>316. Repeated %module directive.
<li>317. Specialization of non-template '<em>name</em>'.
<li>318. Instantiation of template <em>name</em> is ambiguous. Using <em>templ</em> at <em>file</em>:<em>line</em>
<li>319. No access specifier given for base class <em>name</em> (ignored).
<li>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.
<li>353. operator- ignored.
<li>354. operator* ignored.
<li>355. operator/ ignored.
<li>356. operator% ignored.
<li>357. operator^ ignored.
<li>358. operator&amp; ignored.
<li>359. operator| ignored.
<li>360. operator~ ignored.
<li>361. operator! ignored.
<li>362. operator= ignored.
<li>363. operator&lt; ignored.
<li>364. operator&gt; ignored.
<li>365. operator+= ignored.
<li>366. operator-= ignored.
<li>367. operator*= ignored.
<li>368. operator/= ignored.
<li>369. operator%= ignored.
<li>370. operator^= ignored.
<li>371. operator&= ignored.
<li>372. operator|= ignored.
<li>373. operator&lt;&lt; ignored.
<li>374. operator&gt;&gt;ignored.
<li>375. operator&lt;&lt;= ignored.
<li>376. operator&gt;&gt;= ignored.
<li>377. operator== ignored.
<li>378. operator!= ignored.
<li>379. operator&lt;= ignored.
<li>380. operator&gt;= ignored.
<li>381. operator&amp;&amp; ignored.
<li>382. operator|| ignored.
<li>383. operator++ ignored.
<li>384. operator-- ignored.
<li>385. operator, ignored.
<li>386. operator-&lt;* ignored.
<li>387. operator-&lt; ignored.
<li>388. operator() ignored.
<li>389. operator[] ignored.
<li>390. operator+ ignored (unary).
<li>391. operator- ignored (unary).
<li>392. operator* ignored (unary).
<li>393. operator&amp; ignored (unary).
<li>394. operator new[] ignored.
<li>395. operator delete[] ignored.
</ul>
<a name="n11"></a><H3>11.6.4 Types and typemaps (400-499) </H3>
<ul>
<li>401. Nothing known about class 'name'. Ignored.
<li>402. Base class 'name' is incomplete.
<li>403. Class 'name' might be abstract.
<li>450. Deprecated typemap feature ($source/$target).
<li>451. Setting const char * variable may leak memory.
<li>452. Reserved
<li>453. Can't apply (pattern). No typemaps are defined.
<li>460. Unable to use type <em>type</em> as a function argument.
<li>461. Unable to use return type <em>type</em> in function <em>name</em>.
<li>462. Unable to set variable of type <em>type</em>.
<li>463. Unable to read variable of type <em>type</em>.
<li>464. Unsupported constant value.
<li>465. Unable to handle type <em>type</em>.
<li>466. Unsupported variable type <em>type</em>.
<li>467. Overloaded <em>declaration</em> not supported (no type checking rule for '<em>type</em>')
<li>468. No 'throw' typemap defined for exception type 'type'.
</ul>
<a name="n12"></a><H3>11.6.5 Code generation (500-599)</H3>
<ul>
<li>501. Overloaded declaration ignored. <em>decl</em>
<li>502. Overloaded constructor ignored. <em>decl</em>
<li>503. Can't wrap '<em>identifier</em>' unless renamed to a valid identifier.
<li>504. Function <em>name</em> must have a return type.
<li>505. Variable length arguments discarded.
<li>506. Can't wrap varargs with keyword arguments enabled.
<li>507. Adding native function <em>name</em> not supported (ignored).
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator->() at <em>file:line</em>.
<li>509. Overloaded <em>declaration</em> is shadowed by <em>declaration</em> at <em>file</em>:<em>line</em>.
<li>510. Friend function '<em>name</em>' ignored.
<li>511. Can't use keyword arguments with overloaded functions.
<li>512. Overloaded <em>declaration</em> const ignored. Non-const method at <em>file</em>:<em>line</em> used.
<li>513. Can't generate wrappers for unnamed struct/class.
</ul>
<a name="n13"></a><H3>11.6.6 Language module specific (800-899) </H3>
<ul>
<li>801. Wrong name (corrected to '<em>name</em>'). (Ruby).
<li>810. No jni typemap defined for <em>type</em> (Java).
<li>811. No jtype typemap defined for <em>type</em> (Java).
<li>812. No jstype typemap defined for <em>type</em> (Java).
<li>813. Warning for <em>classname</em>: Base <em>baseclass</em> ignored. Multiple inheritance is not supported in Java. (Java).
<li>814. No javagetcptr typemap defined for <em>type</em> (Java).
<li>815. No javafinalize typemap defined for <em>type</em> (Java).
<li>816. No javaptrconstructormodifier typemap defined for <em>type</em> (Java).
<li>817. No javaout typemap defined for <em>type</em> (Java).
<li>818. No javain typemap defined for <em>type</em> (Java).
</ul>
<a name="n14"></a><H3>11.6.7 User defined (900-999)</H3>
These numbers can be used by your own application.
<a name="n15"></a><H2>11.7 History</H2>
The ability to control warning messages was first added to SWIG-1.3.12.
<p><hr>
<address>SWIG 1.3 - Last Modified : Sep 6, 2002</address>
</body>
</html>

180
Doc/Manual/Windows.html Normal file
View File

@ -0,0 +1,180 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Getting started on Windows</title>
</head>
<body bgcolor="#ffffff">
<a name="n1"></a><H1>2 Getting started on Windows </H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Installation on Windows</a>
<ul>
<li><a href="#n3">Windows Executable</a>
</ul>
<li><a href="#n4">SWIG Windows Examples</a>
<ul>
<li><a href="#n5">Instructions for using the Examples with Visual C++</a>
<ul>
<li><a href="#n6">Python</a>
<li><a href="#n7">TCL</a>
<li><a href="#n8">Perl</a>
<li><a href="#n9">Java</a>
<li><a href="#n10">Ruby</a>
</ul>
<li><a href="#n11">Instructions for using the Examples with other compilers</a>
</ul>
<li><a href="#n12">SWIG on Cygwin and Mingw</a>
<ul>
<li><a href="#n13">Building swig.exe on Windows</a>
<ul>
<li><a href="#n14">Building swig.exe using Cygwin and Mingw</a>
<li><a href="#n15">Building swig.exe alternatives</a>
</ul>
<li><a href="#n16">Running the examples on Windows using Cygwin</a>
</ul>
</ul>
<!-- INDEX -->
<a name="n2"></a><H2>2.1 Installation on Windows</H2>
SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
<ul>
<li>Download the swigwin zip package from the <a href="http://www.swig.org">SWIG website</a> and unzip into a directory. This is all that needs downloading for the Windows platform.
<li>Set environment variables as <a href="#windows10">described</a> in order to run some examples using Visual C++.
</ul>
<a name="n3"></a><H3>2.1.1 Windows Executable</H3>
The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP. If you want to build your own swig.exe have a look at the <a href="#cygwin100">supplied instructions</a>.
<p>
<a name="n4"></a><H2>2.2 SWIG Windows Examples</H2>
Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output. The Examples directory has a few Visual C++ project files (.dsp files). These were produced by Visual C++ 6, although they should also work in Visual C++ 5. These project files have been set up to use SWIG in a custom build rule for the SWIG interface (.i) file. Alternatively run the <a href="#cygwin200">examples using Cygwin</a>.<p>
More information on each of the examples is available with the examples on the <a href="../../Examples/index.html">SWIG Examples</a> page which comes with the SWIG installation.
<p>
Note that no SWIG language runtime libraries have been supplied. The examples which have
a Microsoft Visual C++ project file do not need the runtime libraries. In fact the
vast majority of the examples do not need the SWIG runtime libraries.
<a name="n5"></a><H3>2.2.1 Instructions for using the Examples with Visual C++</H3>
Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Each language requires some environment variables to be set <b>before</b> running Visual C++. Note that Visual C++ must be re-started to pick up any changes in environment variables. Open up the .dsp file, Visual C++ will create a workspace for you (.dsw file). Do a Rebuild All from the Build menu; the required environment variables are displayed with their current values. <p>
The list of required environment variables for each module language is also listed below. They are usually set from the Control Panel and System properties, but this depends on which flavour of Windows you are running. If you don't want to use environment variables then change all occurences of the environment variables in the .dsp files with hard coded values.
If you are interested in how the project files are set up have a look at the section on building extensions for your chosen language module.
<a name="n6"></a><H4>2.2.1.1 Python</H4>
<b><tt>PYTHON_INCLUDE</tt></b> : Set this to the directory that contains python.h<br>
<b><tt>PYTHON_LIB</tt></b> : Set this to the python library including path for linking with<p>
Example using Python 2.1.1:<br>
<tt>
PYTHON_INCLUDE: d:\python21\include<br>
PYTHON_LIB: d:\python21\libs\python21.lib<br>
</tt>
<a name="n7"></a><H4>2.2.1.2 TCL</H4>
<b><tt>TCL_INCLUDE</tt></b> : Set this to the directory containing tcl.h<br>
<b><tt>TCL_LIB</tt></b> : Set this to the TCL library including path for linking with<p>
Example using ActiveTcl 8.3.3.3 <br>
<tt>
TCL_INCLUDE: d:\tcl\include<br>
TCL_LIB: d:\tcl\lib\tcl83.lib<br>
</tt>
<a name="n8"></a><H4>2.2.1.3 Perl</H4>
<b><tt>PERL5_INCLUDE</tt></b> : Set this to the directory containing perl.h and perl.lib<br>
Example using nsPerl 5.004_04:<p>
<tt>
PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE<br>
</tt>
<a name="n9"></a><H4>2.2.1.4 Java</H4>
<b><tt>JAVA_INCLUDE</tt></b> : Set this to the directory containing jni.h<br>
<b><tt>JAVA_BIN</tt></b> : Set this to the bin directory containing javac.exe<p>
Example using JDK1.3:<br>
<tt>
JAVA_INCLUDE: d:\jdk1.3\include<br>
JAVA_BIN: d:\jdk1.3\bin<br>
</tt>
<a name="n10"></a><H4>2.2.1.5 Ruby</H4>
<b><tt>RUBY_INCLUDE</tt></b> : Set this to the directory containing ruby.h<br>
<b><tt>RUBY_LIB</tt></b> : Set this to the ruby library including path for linking with<p>
Example using Ruby 1.6.4:<br>
<tt>
RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32<br>
RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib<br>
</tt>
<a name="n11"></a><H3>2.2.2 Instructions for using the Examples with other compilers</H3>
If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.
<a name="n12"></a><H2>2.3 SWIG on Cygwin and Mingw</H2>
SWIG can also be compiled and run using <a href="http://www.cygwin.com">Cygwin</a> which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied.
<a name="n13"></a><H3>2.3.1 Building swig.exe on Windows</H3>
If you want to replicate the build of swig.exe that comes with the download, follow the following instructions.
This is not necessary to use the supplied swig.exe. This information is provided for
those that want to modify the SWIG source code in a Windows environment. Normally this is not needed, so most people will want to ignore this section.
<a name="n14"></a><H4>2.3.1.1 Building swig.exe using Cygwin and Mingw</H4>
<ul>
<li>Install <a href="http://www.cygwin.com">Cygwin</a>
<li>Install <a href="http://www.mingw.org">Mingw</a>
<li>Ensure that the Mingw bin directory is before the Cygwin bin directory in your path.
<li>Follow the usual Unix instructions in the README file in the SWIG root directory to build swig.exe.
</ul>
Try running <tt>./autogen.sh</tt> from the SWIG root directory before running <tt>./configure</tt> if you have the latest autotools installed and want to use them (usually recommended).
<p>
Note that SWIG can be built using just Cygwin, i.e. no Mingw installed. However, the
SWIG executable will then require the Cygwin DLL.
<p>
<a name="n15"></a><H4>2.3.1.2 Building swig.exe alternatives</H4>
If you don't want to install Cygwin and Mingw, use a different compiler to build
SWIG. For example, all the source code files can be added to a Visual C++ project
file in order to build swig.exe from the Visual C++ IDE.
<a name="n16"></a><H3>2.3.2 Running the examples on Windows using Cygwin</H3>
Starting with SWIG-1.3.12 the examples and test-suite work almost as successfully on Cygwin (not using Mingw) as on any other Unix operating system. The modules which are known to work are Python, Tcl, Perl, Ruby and Java, but none of the runtime libraries. Follow the Unix instructions in the README file in the SWIG root directory to build the examples.
<p>
You may need to run <tt>./autogen.sh</tt> from the SWIG root directory before running <tt>./configure</tt> if you have the latest autotools installed and want to use them (usually recommended).
</body>
</html>

BIN
Doc/Manual/ch11.1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
Doc/Manual/ch11.2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Doc/Manual/ch11.3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
Doc/Manual/ch12.1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
Doc/Manual/ch2.1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Doc/Manual/ch9.table.2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

23
Doc/Manual/chapters Normal file
View File

@ -0,0 +1,23 @@
Preface.html
Introduction.html
Windows.html
Scripting.html
SWIG.html
SWIGPlus.html
Preprocessor.html
Arguments.html
Typemaps.html
Customization.html
Varargs.html
Warnings.html
Library.html
Advanced.html
Guile.html
Java.html
Ocaml.html
Perl5.html
Php.html
Python.html
Ruby.html
Tcl.html
Extending.html

92
Doc/Manual/index.html Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG1.3 Documentation</title>
</head>
<body bgcolor="#ffffff">
<H1>SWIG1.3 Development Documentation</h1>
Last update : SWIG-1.3.17 (22 November 2002)
<p>
<b>Authors:</b>
<ul>
<li>David Beazley (beazley@cs.uchicago.edu)
<li>William Fulton (wsf@fultondesigns.co.uk)
<li>Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de)
<li>Lyle Johnson (lyle@users.sourceforge.net)
<li>Richard Palmer (richard@magicality.org)
<li>Craig Files (cfiles@ftc.agilent.com)</li>
<li>Art Yerkes (ayerkes@users.sourceforge.net)</li>
</ul>
<P>
The SWIG documentation is currently being updated to reflect new SWIG
features and enhancements. However,this update process is currently
unfinished--there is a lot of old SWIG-1.1 documentation and it's going to
take some time to update all of it. Please pardon our dust (or volunteer
to help!).
<p>
<h3><a href="Contents.html">Detailed table of contents</a></h3>
<p>
<H3>SWIG Core Documentation</H3>
<ul>
<li><a href="Preface.html">Preface</a>
<li><a href="Introduction.html">Introduction</a>
<li><a href="Windows.html">Getting started on Windows</a>
<li><a href="Scripting.html">Scripting</a>
<li><a href="SWIG.html">SWIG Basics</a> (Read this!)
<li><a href="SWIGPlus.html">SWIG and C++</a>
<li><a href="Preprocessor.html">The SWIG preprocessor</a>.
<li><a href="Library.html">The SWIG Library</a>
<li><a href="Arguments.html">Argument handling</a>.
<li><a href="Typemaps.html">Typemaps</a>
<li><a href="Customization.html">Customization features</a>
<li><a href="Varargs.html">Variable length arguments</a>
<li><a href="Warnings.html">Warning messages</a>
</ul>
<H3>Language Module Documentation</h3>
<ul>
<li><a href="Guile.html">Guile support</a>
<li><a href="Java.html">Java support</a>
<li><a href="Ocaml.html">Ocaml support</a>
<li><a href="Perl5.html">Perl5 support</a>
<li><a href="Php.html">PHP support</a>
<li><a href="Python.html">Python support</a>
<li><a href="Ruby.html">Ruby support</a>
<li><a href="Tcl.html">Tcl support</a>
</ul>
<H3>Developer Documentation</h3>
<ul>
<li><a href="Extending.html">Extending SWIG</a>
</ul>
<p>
<h3>Documentation that has not yet been updated</h3>
This documentation has not been updated, but most of the topics
still apply to the current release. Make sure you read the
<a href="SWIG.html">SWIG Basics</a> chapter before reading
any of these chapters. Also, SWIG-1.3.10 features extensive changes to the
implementation of typemaps. Make sure you read the <a href="Typemaps.html">Typemaps</a>
chapter above if you are using this feature.
<ul>
<li><a href="Advanced.html">Advanced topics</a>
</ul>
<h3>Documentation not yet written</h3>
<ul>
<li>Mzscheme module
</ul>
</body>
</html>

139
Doc/Manual/makechap.py Normal file
View File

@ -0,0 +1,139 @@
#!/usr/local/bin/python
# Takes a chapter as input and adds internal links and numbering to all
# of the h1, h2, h3, h4 sections and so forth.
#
import sys
import re
if len(sys.argv) != 3:
print "usage: makechap.py filename num"
sys.exit(1)
filename = sys.argv[1]
num = int(sys.argv[2])
section = 0
subsection = 0
subsubsection = 0
nameindex = 0
name = ""
# Regexs for <h1>,... <h4> sections
h1 = re.compile(r".*?<H1>[\d\.\s]*(.*?)</H1>", re.IGNORECASE)
h2 = re.compile(r".*?<H2>[\d\.\s]*(.*?)</H2>", re.IGNORECASE)
h3 = re.compile(r".*?<H3>[\d\.\s]*(.*?)</H3>", re.IGNORECASE)
h4 = re.compile(r".*?<H4>[\d\.\s]*(.*?)</H4>", re.IGNORECASE)
data = open(filename).read() # Read data
open(filename+".bak","w").write(data) # Make backup
lines = data.splitlines()
result = [ ]
index = "<!-- INDEX -->\n<ul>\n"
skip = 0
skipspace = 0
for s in lines:
if s == "<!-- INDEX -->":
if not skip:
skip = 1
else:
skip = 0
continue;
if skip:
continue
if not s and skipspace:
continue
if skipspace:
result.append("")
result.append("")
skipspace = 0
m = h1.match(s)
if m:
nameindex += 1
result.append("""<a name="n%d"></a><H1>%d %s</H1>""" % (nameindex,num,m.group(1)))
result.append("@INDEX@")
section = 0
subsection = 0
subsubsection = 0
name = m.group(1)
skipspace = 1
continue
m = h2.match(s)
if m:
nameindex += 1
section += 1
result.append("""<a name="n%d"></a><H2>%d.%d %s</H2>""" % (nameindex,num,section, m.group(1)))
if subsubsection:
index += "</ul>\n"
if subsection:
index += "</ul>\n"
index += """<li><a href="#n%d">%s</a>\n""" % (nameindex,m.group(1))
subsection = 0
subsubsection = 0
skipspace = 1
continue
m = h3.match(s)
if m:
nameindex += 1
subsection += 1
result.append("""<a name="n%d"></a><H3>%d.%d.%d %s</H3>""" % (nameindex,num,section, subsection, m.group(1)))
if subsubsection:
index += "</ul>\n"
if subsection == 1:
index += "<ul>\n"
index += """<li><a href="#n%d">%s</a>\n""" % (nameindex,m.group(1))
subsubsection = 0
skipspace = 1
continue
m = h4.match(s)
if m:
nameindex += 1
subsubsection += 1
result.append("""<a name="n%d"></a><H4>%d.%d.%d.%d %s</H4>""" % (nameindex,num,section, subsection, subsubsection, m.group(1)))
if subsubsection == 1:
index += "<ul>\n"
index += """<li><a href="#n%d">%s</a>\n""" % (nameindex,m.group(1))
skipspace = 1
continue
result.append(s)
if subsubsection:
index += "</ul>\n"
if subsection:
index += "</ul>\n"
if section:
index += "</ul>\n"
index += "<!-- INDEX -->\n"
data = "\n".join(result)
data = data.replace("@INDEX@",index);
# Write the file back out
open(filename,"w").write(data)
# Print the TOC data
index = index.replace("#n","%s#n" % filename)
print """<h3><a href="%s">%d %s</a></h3>\n""" % (filename,num,name)
print index

36
Doc/Manual/maketoc.py Normal file
View File

@ -0,0 +1,36 @@
#!/usr/local/bin/python
import sys
import os
chs = open("chapters").readlines()
f = open("Contents.html","w")
print >>f, """
<HTML>
<HEAD>
<TITLE>SWIG Users Manual</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
<H1>SWIG Users Manual</H1>
<p>
"""
f.close()
num = 0
for c in chs:
c = c.strip()
print "Processing %s" % c
if c:
os.system("python makechap.py %s %d >> Contents.html" % (c,num))
num += 1
f = open("Contents.html","a")
print >>f, """
</BODY>
</HTML>
"""

5
Doc/README Normal file
View File

@ -0,0 +1,5 @@
Doc/Manual - Latest version of the SWIG user manual
Doc/Devel - Developer documentation concerning SWIG internals.
(not necessarily up to date)

View File

@ -1,363 +0,0 @@
<html>
<head>
<title>SWIG Project Overview</title>
</head>
<body bgcolor="#ffffff">
<center>
<h1>The SWIG Redevelopment Effort</h1>
<b>David Beazley <br>
Department of Computer Science <br>
University of Chicago <br>
Chicago, IL 60637 <br>
beazley@cs.uchicago.edu <br>
</b>
</center>
<p>
<b>$Header$</b>
<p>
<h2>1. An Introduction</h2>
One of the biggest problems faced by people writing software is the
problem how to make software easier to use, more interactive, and more
modular. Typically, the computer science community has approached
these problems by focusing on formal design methodology and highly
specified frameworks built around notions of software components,
object-oriented programming, and anything labeled as "best practice"
(whatever that means). Although this type of approach is perhaps
appropriate for very large software projects involving hundreds of
programmers, software engineers, and managers, I've never met a sane
programmer who really enjoys writing software in such an environment.
Furthermore, a large number of software projects are undertaken by
small groups of people who would not classify themselves as
professional software developers or software engineers. Typical
examples might include scientific computing software, specialized
systems for engineering applications, or just about any kind of
experimental research and development project. These are the types of
programming projects "in the small" that are my primary interest.
<p>
First, programming projects in the small should not be confused with
the toy programs one might write as part of a class project or when
solving exceedingly trivial problems. More often that not, a software
package written by only a few people may have been developed over a
period of several years and may contain of hundreds of thousands of
lines of source code. Furthermore, due to limited manpower, these
projects are likely to rely on a variety of third-party packages and
programming libraries to accomplish certain tasks. Finally, it is not
uncommon for such software to have been developed in a relatively
piecemeal fashion with little if any formal design. The developers
may also be burdened with the task of supporting a large base of
legacy code that is critical to the application, but which is too
complicated to simply rewrite from scratch. As a result, the software
developed in such an environment may be a tangled web of code that
gets the job done, but which is less than ideal in terms of its
usuability and overall design.
<p>
Of course, one does not need to look very far to see examples of this
kind of development. For instance, I would claim that just about
every successful project within the Open Source community has been
developed in this way. As a more specific example, Swig itself was
developed in a relatively adhoc manner over a period of two years.
Although it was my intent to have a relatively clean design at the
start, the system has since evolved into a very tangled mess of
monolithic C++ code. It's not that I wanted to end up in this
situation--rather the experience gained by Swig's early users pushed
the system in an unanticipated direction that the original design
failed to address. In many ways, it is ironic that SWIG should end up
in this particular state given that this is <em>exactly</em> the type
of situation that Swig was built to address!
<p>
Naturally, this brings us to the overall motivation behind SWIG itself.
In a nutshell, SWIG is a software development tool that aims to make it
easier to do the following:
<ul>
<li>Build user interfaces to existing software. For example, the
primary reason for Swig's emphasis on scripting languages is not that
scripting languages are cool (which they are). It is that interpreters
make great user interfaces for a wide variety of applications.
Furthermore, interpreters can be used to build more advanced user
interfaces using toolkits such as Tk.
<p>
<li>Repackage an existing system as a collection of modules. The primary
motivation for this is that working with software organized as a collection
of loosely coupled modules generally results in greater flexibility and
reduced maintainance cost in comparison to a huge monolithic package. Since
scripting languages naturally promote the creation of modules and Swig makes it
easy to integrate scripting languages with existing software, Swig also serves
as a module building tool.
<p>
<li>Work with software in a rapidly changing, experimental, and
underspecified environment. One of the reasons why people don't like
formal component frameworks and over-specification is that they may
not know how a system is actually going to look or evolve when they
start a project. As a result, excessive formality is viewed as more
of a burden than a benefit. Swig, in a sense, turns this whole
scenario around by being highly adaptable and allowing the programmer
to write the software however they want as opposed to forcing programs to
be written within a rigidly defined set of rules.
<p>
<li>Serve as a rapid prototyping and testing tool. Given the
non-invasive way in which Swig works with existing software, it allows
developers to experiment with different modules, languages, and
methods of organizing a system. As a result, Swig can be used in the
prototyping and development stages of a project even if the final
package makes no use of Swig, scripting, or any of its related
modules.
</ul>
I also want to emphasize that <b>the target users of Swig are not professional
software engineers.</b> Rather the system is designed to be very easy to use for
more ordinary people who just happen to be working on programming projects as
part of their work or for fun (physicists, engineers, hackers, etc...). It is also
designed to provide a certain element of "instant gratification" if you will. I believe that
the following quotes from a SWIG user survey put things in the right perspective:
<ul>
<li> "Easy to use, no need to worry about language internals. It is a boon for application
developers, like me."
<p>
<li>"I really love the fact that the learning curve is short and flat."
<p>
<li>"Since SWIG has proven to be rather easy to use, I find I can carry out
the types of wrapping activities which would otherwise have been the responsibility
of a computer scientist."
<p>
<li>"I came, I saw, I wrapped. And it ran. Woo hoo!"
</ul>
<h2>2. Problems with SWIG</h2>
Despite the early success of SWIG, the system suffers from a number of serious
limitations. Furthermore, these problems are not easily fixed within the current
design.
<ul>
<li><b>The C/C++ parser is incomplete</b>. SWIG only understands a
limited subset of C and is based on an incorrect representation of C
datatypes that prevents the proper handling of "const", references,
pointers to functions, and other more complex types. In addition,
fundamental things like C++ function overloading still don't
work. Although 99% of the common cases work and there are workarounds
for certain situations, these limitations are still annoying.
<p>
<li><b>The SWIG module system is all wrong</b>. In the current
implementation, SWIG modules are created using C++ inheritance. This
has a number of unintended consequences. First, it restricts the
functionality of a module to a fixed
set of virtual function calls made deep inside the parsing engine. As
a result, it is not possible to write highly specialized modules that
don't quite fit into the normal module scheme. Second, it makes the
module system unnecesarily complicated and too tightly coupled. For
instance, there is no way to write a module that operates outside of
the SWIG framework or which might be useful on its own. Finally, I
believe that the C++ module system alienates the user community
because it is too complicated and there aren't that many C++ programmers. With a simpler
module interface, I believe that the system would be much more accessible
to the user community and people who want to write modules.
<p>
<li><b>Why stop at C and scripting?</b>. Although SWIG does a great
job of building scripting interfaces, there is no practical reason to
restrict its functionality in this way. For one, it is probably
worthwhile to consider alternative input languages including Fortran
and CORBA IDL. Second, there are a variety of secondary tasks that
one might be able to do with such a system such as analyze the
structure of application interfaces, generate documentation, provide
interfaces to databases, and provide tools to help modularize existing
software. Although these sound like lofty goals, I believe that the system
should be flexible enough to allow such applications.
</ul>
Of course, the real trick is how one goes about solving these issues
without making Swig excessively complicated--both from the point of
development and use.
<h2>3. SWIG Redevelopment: Modules</h2>
Simply stated, the primary goal of SWIG redevlopment is to redesign
the SWIG compiler as an extensible set of loosely coupled modules
(<b>Note: it is not my intent to radically change the way in which an
end-user uses SWIG</b>).
In this context, my intent is to allow a module to be virtually anything
that might be part of a compiler or which would interact with a
compiler in some manner. For example:
<ul>
<li> Preprocessors.
<li> Parsers.
<li> Code generators.
<li> Code browsers.
<li> Documentation generators.
<li> Optimizers.
<li> Testing tools.
<li> Other development environments.
</ul>
Unfortunately, as programs go, compilers tend to be extremely
complicated. Therefore, to make any sort of module system work, the
mechanism by which modules interact and exchange data needs to be
extremely powerful and extremely simple.
<p>
To address these problems, SWIG redevelopment is based on a few fundamental ideas:
<ol>
<li>All data will be internally represented using an XML-like scheme
in which every piece of data is identified by a unique element "tag"
and a set of associated attributes. Manipulation of the data in turn
will involve nothing more than making an appropriate association of
the "tags" with some sort of "action" to be performed. Unlike an
approach in which objects are placed into a rigid C++ class hierarchy,
the XML-based approach allows a virtually unlimited number of
different object types and attributes to be created and manipulated without ever
having to recompile anything. As a result, this would allow modules to easily
extend the system in novel ways. It should also be added that this
data representation greatly simplifies the underlying core of
the system because an XML-like representation can be
built entirely using nothing more than a hash-table object and a
few fundamental datatypes such as strings and lists.
<p>
<li>All underlying data structures will be built using a dynamic type
handling mechanism and a small collection of fundamental datatypes
including strings, lists, and hash tables. There are several
advantages to this approach. First, dynamic typing generally results
in substantially less code if done correctly. For instance, in my
own experiences using Objective-C vs. C++, I found that my dynamically
typed Objective-C programs were up to 5 times smaller than their C++
counterparts. Furthermore, dynamic typing is also one of the reasons
why scripting languages are so powerful.
<p>
<li>
Modules will interact with each other and exchange data using the XML-scheme
previously described. Due to the flexibility of this approach, this allows
modules to be written in a relatively stand-alone manner. Furthermore, the
use of XML may simplify the development of external tools that do not share
any commonality with the SWIG executable or its internal data structures.
<p>
<li>Dynamic loading. Closely associated with loose-coupling, the SWIG module
system should optionally support dynamic loading of compiler modules. This might
be accomplished in two ways. First, I believe that SWIG itself should
provide a scripting interface that allows its modules to be dynamically
loaded into a variety of scripting languages. Second, SWIG
should probably implement some sort of module loading system that allows modules
to be used without the optional scripting interace.
</ol>
Finally, it should be noted that the implementation language of choice for
the SWIG redevelopment effort is ANSI C. There are several reasons for this:
<ul>
<li> ANSI C is highly portable and available everywhere.
<li> C provides the performance necessary to implement a few critical aspects of a compiler.
<li> C is the ultimate glue-language in the sense that it can be interfaced
with just about anything if you know what you are doing. This will be especially important
if we want to interface with third-party compiler construction tools.
<li> It is perhaps the most widely spoken programming language--making it a good choice
to encourage community involvement and the creation of additional SWIG modules.
<li> Dave likes it.
</ul>
<h2>4. The Initial Module Set</h2>
The following list describes the proposed modules that will be part of the new
system:
<ul>
<li><b>Swig</b>. The Swig module contains a small core of functionality that is used
by the rest of the system. Features include access to the Swig library, command line
parsing, error handling, and a few common datatypes including a somewhat generic representation of
types.
<p>
<li><b>DOH</b>. DOH is the dynamic type library that provides the fundamental
data structures used by the system as well as run-time support for dynamic typing.
<p>
<li><b>Preprocessor</b>. A full C/C++ preprocessor with some extended macro handling
capabilities.
<p>
<li><b>LParse</b>. A SWIG1.1 compatible parser generator that can read the older SWIG interface
files and produce an appropriate parse-tree compatible with the new system. This parser
will primarily be used for backwards compatibility as well as issuing appropriate warnings
to the user about deprecated features. This parsing module will also be used until the
CParse module is completed.
<p>
<li><b>CParse</b>. A completely redesigned C/C++ parser that attempts to fix all of the parsing
problems in SWIG1.1. In particular, it will treat C/C++ datatypes correctly and support a
number of new C++ constructs. However, it is somewhat unlikely that this parser will
fully support all of C++ (at least not initially).
<p>
<li><b>SWIM</b>. The SWIG Monitor. This is utility module that allows users to browse
through internal compiler data structures using a web browser. This is primarily intended
for development purposes, but may evolve into a general purpose interface browsing
tool.
<p>
<li><b>SWILL</b>. The SWIG Web Interface Link Library. This is a generic library that
can be used to add a web server to an application. Although developed independently of
SWIG, it is used by the SWIM module above.
<p>
<li><b>XMLParse</b>. A parsing module that can read XML files and turn them into a SWIG parse
tree structure. The initial plan is to simply put a thin wrapper around the expat for this.
<p>
<li><b>XMLWriter</b>. A code generation module that can simply dump all of the internal
data structures out as a huge XML document.
<p>
<li><b>Tcl</b>. A code generator for Tcl.
<p>
<li><b>Perl</b>. A code generator for Perl.
<p>
<li><b>Python</b>. A code generator for Python.
<p>
<li><b>Guile</b>. A code generator for Guile.
<p>
<li><b>Java</b>. A code generator for Java.
<p>
<li><b>Testing</b>. A testing module that is designed to aid in the construction
of testing scripts. More details to be provided later.
<p>
<li><b>Documentation</b>. A replacement for the SWIG1.1 documentation generation
system. The precise details need to be determined, but it is likely that this
system will produce both plain ASCII files or XML files.
</ul>
</body>
</html>

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,21 @@
/* Oh what the heck, let's just grab the whole darn header file
and see what happens. */
%module gifplot
%{
/* Note: You still need this part because the %include directive
merely causes SWIG to interpret the contents of a file. It doesn't
include the right include headers for the resulting C code */
#include "gifplot.h"
%}
/* Pixel is typedef'd to unsigned char, and SWIG will translate this
type into Scheme characters. We would like to translate Pixels to
Scheme integers instead, so: */
SIMPLE_MAP(Pixel, gh_scm2int, gh_int2scm, integer);
%include gifplot.h

View File

@ -0,0 +1,59 @@
;;; Plot a 3D function
;; Here is the function to plot
(defun func (x y)
(* 5
(cos (* 2 (sqrt (+ (* x x) (* y y)))))
(exp (* -0.3 (sqrt (+ (* x x) (* y y)))))))
;; Here are some plotting parameters
(defvar xmin -5D0)
(defvar xmax 5D0)
(defvar ymin -5D0)
(defvar ymax 5D0)
(defvar zmin -5D0)
(defvar zmax 5D0)
;; Grid resolution
(defvar nxpoints 60)
(defvar nypoints 60)
(defun drawsolid (p3)
(Plot3D-clear p3 0)
(Plot3D-start p3)
(let ((dx (/ (- xmax xmin) nxpoints))
(dy (/ (- ymax ymin) nypoints))
(cscale (/ 240 (- zmax zmin))))
(loop for x from xmin by dx
repeat nxpoints
do (loop for y from ymin by dy
repeat nypoints
do (let* ((z1 (func x y))
(z2 (func (+ x dx) y))
(z3 (func (+ x dx) (+ y dy)))
(z4 (func x (+ y dy)))
(c1 (* cscale (- z1 zmin)))
(c2 (* cscale (- z2 zmin)))
(c3 (* cscale (- z3 zmin)))
(c4 (* cscale (- z4 zmin)))
(cc (/ (+ c1 c2 c3 c4) 4))
(c (round (max (min cc 239) 0))))
(Plot3D-solidquad p3 x y z1 (+ x dx) y z2 (+ x dx) (+ y dy)
z3 x (+ y dy) z4 (+ c 16)))))))
(defun action (cmap-filename)
(let ((cmap (new-ColorMap cmap-filename))
(frame (new-FrameBuffer 500 500)))
(format t "Making a nice 3D plot...~%")
(FrameBuffer-clear frame 0)
(let ((p3 (new-Plot3D frame xmin ymin zmin xmax ymax zmax)))
(Plot3D-lookat p3 (* 2 (- zmax zmin)))
(Plot3D-autoperspective p3 40D0)
(Plot3D-rotu p3 60D0)
(Plot3D-rotr p3 30D0)
(Plot3D-rotd p3 10D0)
(drawsolid p3))
(FrameBuffer-writeGIF frame cmap "/tmp/image.gif")
(format t "Wrote image.gif~%")))

View File

@ -0,0 +1,3 @@
# see top-level Makefile.in
full
simple

View File

@ -0,0 +1,3 @@
gifplot-guile
gifplot_wrap.c
image.gif

View File

@ -5,23 +5,24 @@ SRCS =
TARGET = gifplot
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot -lm
INCLUDE = -I../../Include
INCLUDES = -I../../Include
all:: static
dynamic::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile
static::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile_static
clean::
rm -f *_wrap* *.o *~ *.so gifguile .~* core *.gif
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean
rm -f *.gif
check: all

View File

@ -0,0 +1,4 @@
gifguile
image.gif
simple-guile
simple_wrap.c

View File

@ -5,23 +5,24 @@ SRCS =
TARGET = simple
INTERFACE = simple.i
LIBS = -L../.. -lgifplot
INCLUDE = -I../../Include
INCLUDES = -I../../Include
all:: static
dynamic::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile
static::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile_static
clean::
rm -f *_wrap* *.o *~ *.so gifguile .~* core *.gif
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean
rm -f *.gif
check: all

View File

@ -18,6 +18,10 @@
#ifndef GIFPLOT_H
#ifdef SWIG
%pragma no_default
#endif
/* Pixel is 8-bits */
typedef unsigned char Pixel;
@ -125,9 +129,9 @@ extern void delete_PixMap(PixMap *pm);
extern void PixMap_set(PixMap *pm, int x, int y, int pix);
extern void FrameBuffer_drawpixmap(FrameBuffer *f, PixMap *pm, int x, int y, int fgcolor, int bgcolor);
#define TRANSPARENT 0
#define FOREGROUND 1
#define BACKGROUND 2
#define GIFPLOT_TRANSPARENT 0
#define GIFPLOT_FOREGROUND 1
#define GIFPLOT_BACKGROUND 2
/* ------------------------------------------------------------------------
Plot2D

View File

@ -11,8 +11,6 @@
typedef unsigned char Pixel;
typedef float Zvalue;
%disabledoc
/* ------------------------------------------------------------------------
ColorMap
@ -23,14 +21,14 @@ typedef struct ColorMap {
char *name;
//
// %addmethods adds some C methods to this structure to make it
// %extend adds some C methods to this structure to make it
// look like a C++ class in Python.
// These are really named things like ColorMap_default, ColorMap_assign, etc...
%addmethods {
%extend {
ColorMap(char *filename);
~ColorMap();
#ifdef SWIGJAVA
#if defined(SWIGJAVA ) || defined(SWIGPHP4)
%name(make_default) void default();
#else
void default();
@ -44,16 +42,6 @@ typedef struct ColorMap {
/* Some default colors */
#ifdef SWIGJAVA
const Pixel BLACK = 0;
const Pixel WHITE = 1;
const Pixel RED = 2;
const Pixel GREEN = 3;
const Pixel BLUE = 4;
const Pixel YELLOW = 5;
const Pixel CYAN = 6;
const Pixel MAGENTA = 7;
#else
#define BLACK 0
#define WHITE 1
#define RED 2
@ -62,7 +50,6 @@ const Pixel MAGENTA = 7;
#define YELLOW 5
#define CYAN 6
#define MAGENTA 7
#endif
/*-------------------------------------------------------------------------
FrameBuffer
@ -77,7 +64,7 @@ typedef struct FrameBuffer {
int ymin;
int xmax;
int ymax;
%addmethods {
%extend {
FrameBuffer(unsigned int width, unsigned int height);
~FrameBuffer();
void resize(int width, int height);
@ -119,9 +106,9 @@ extern PixMap *new_PixMap(int width, int height, int centerx, int centery);
extern void delete_PixMap(PixMap *pm);
extern void PixMap_set(PixMap *pm, int x, int y, int pix);
#define TRANSPARENT 0
#define FOREGROUND 1
#define BACKGROUND 2
#define GIFPLOT_TRANSPARENT 0
#define GIFPLOT_FOREGROUND 1
#define GIFPLOT_BACKGROUND 2
/* --------------------------------------------------------------------------
Plot2D
@ -141,7 +128,7 @@ typedef struct Plot2D {
double ymax;
int xscale; /* Type of scaling (LINEAR, LOG, etc..) */
int yscale;
%addmethods {
%extend {
Plot2D(FrameBuffer *frame,double xmin,double ymin, double xmax, double ymax);
~Plot2D();
Plot2D *copy();
@ -203,7 +190,7 @@ typedef struct Plot3D {
double lookatz; /* Where is the z-lookat point */
double xshift; /* Used for translation and stuff */
double yshift;
%addmethods {
%extend {
Plot3D(FrameBuffer *frame, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax);
~Plot3D();
Plot3D *copy();
@ -264,13 +251,11 @@ typedef struct Plot3D {
/* These directives create constants of a specific type. They
do not correspond to any C variable or declared constant in the
header file */
%constant(PixMap *) SQUARE = &PixMap_SQUARE;
%constant(PixMap *) TRIANGLE = &PixMap_TRIANGLE;
%constant(PixMap *) CROSS = &PixMap_CROSS;
%constant PixMap * SQUARE = &PixMap_SQUARE;
%constant PixMap * TRIANGLE = &PixMap_TRIANGLE;
%constant PixMap * CROSS = &PixMap_CROSS;
#endif
%enabledoc

View File

@ -1,18 +0,0 @@
TOP = ../..
SWIG = $(TOP)/../swig -shadow
SWIGOPT = -I../Include
SRCS =
TARGET = libjgifplot
INTERFACE = gifplot.i
LIBS = -L.. -lgifplot -lm
INCLUDE = -I../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java
clean::
rm -f *_wrap* *.o *~ *.so .~* core *.gif *.class ColorMap.java FrameBuffer.java Plot2D.java Plot3D.java gifplot.java
check: all

View File

@ -1,30 +0,0 @@
The gifplot example does not work straight out of the box,
I had to change ../Interface/gifplot.i slightly for java.
a)
The colors (e.g. BLACK) where defined as:
#define BLACK 0
and the functions expect 'Pixel color' where Pixel is a unsigned char.
#define constants contain no type information and are translated to integer
constants. Because of that, you have to cast every Pixel to a byte in java.
Changing the definition to:
const Pixel BLACK = 0;
fixes this.
b)
The definitions:
const PixMap *SQUARE = &PixMap_SQUARE;
const PixMap *TRIANGLE = &PixMap_TRIANGLE;
const PixMap *CROSS = &PixMap_CROSS;
don't work.
The wrapper code expects actual variables SQUARE, etc. and they are not
defined in gifplot.h.
c)
In shadow mode the method ColorMap::default() clashes with the reserved name
default.

View File

@ -0,0 +1,4 @@
# see top-level Makefile.in
full
shadow
simple

Binary file not shown.

View File

@ -0,0 +1,7 @@
*.class
*.java
*_wrap.c
*_wrap.cxx
*.so
*.dll
*.gif

View File

@ -0,0 +1,20 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -I../../Include -noproxy
SRCS =
TARGET = gifplot
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot
INCLUDES = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java
javac *.java
clean::
$(MAKE) -f $(TOP)/Makefile java_clean
rm -f *.gif
check: all

View File

@ -0,0 +1,8 @@
This example runs the entire gifplot.h header file through SWIG without
any changes. The program 'main.java' does something a little more
interesting. After doing a make, run it using 'java main'. You'll have to go
look at the header file to get a complete listing of the functions.
Note the differences in the main.java files between this example and the
'full' example. This example does not use shadow classes.

Binary file not shown.

View File

@ -0,0 +1,15 @@
/* Oh what the heck, let's just grab the whole darn header file
and see what happens. */
%module gifplot
%{
/* Note: You still need this part because the %include directive
merely causes SWIG to interpret the contents of a file. It doesn't
include the right include headers for the resulting C code */
#include "gifplot.h"
%}
%include gifplot.h

View File

@ -0,0 +1,75 @@
// Plot a 3D function
import java.lang.Math;
public class main {
static {
try {
System.loadLibrary("gifplot");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
// Here are some plotting parameters
double xmin = -5.0;
double xmax = 5.0;
double ymin = -5.0;
double ymax = 5.0;
double zmin = -5.0;
double zmax = 5.0;
// Grid resolution
int nxpoints = 60;
int nypoints = 60;
SWIGTYPE_p_ColorMap cmap = gifplot.new_ColorMap("cmap");
SWIGTYPE_p_FrameBuffer frame = gifplot.new_FrameBuffer(500,500);
gifplot.FrameBuffer_clear(frame,(short)gifplot.BLACK);
SWIGTYPE_p_Plot3D p3 = gifplot.new_Plot3D(frame,xmin,ymin,zmin,xmax,ymax,zmax);
gifplot.Plot3D_lookat(p3,2*(zmax-zmin));
gifplot.Plot3D_autoperspective(p3,40);
gifplot.Plot3D_rotu(p3,60);
gifplot.Plot3D_rotr(p3,30);
gifplot.Plot3D_rotd(p3,10);
System.out.println( "Making a nice 3D plot..." );
gifplot.Plot3D_clear(p3,(short)gifplot.BLACK);
gifplot.Plot3D_start(p3);
double dx = 1.0*(xmax-xmin)/nxpoints;
double dy = 1.0*(ymax-ymin)/nypoints;
double cscale = 240.0/(zmax-zmin);
double x = xmin;
for (int i = 0; i < nxpoints; i++) {
double y = ymin;
for (int j = 0; j < nypoints; j++) {
double z1 = func(x,y);
double z2 = func(x+dx,y);
double z3 = func(x+dx,y+dy);
double z4 = func(x,y+dy);
double c1 = cscale*(z1-zmin);
double c2 = cscale*(z2-zmin);
double c3 = cscale*(z3-zmin);
double c4 = cscale*(z4-zmin);
double c = (c1+c2+c3+c4)/4;
if (c < 0) c = 0;
if (c > 239) c = 239;
gifplot.Plot3D_solidquad(p3,x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,(short)(c+16));
y = y + dy;
}
x = x + dx;
}
gifplot.FrameBuffer_writeGIF(frame,cmap,"image.gif");
System.out.println( "Wrote image.gif" );
}
// Here is the function to plot
public static double func(double x, double y) {
return 5*java.lang.Math.cos(2*java.lang.Math.sqrt(x*x+y*y))*java.lang.Math.exp(-0.3*java.lang.Math.sqrt(x*x+y*y));
}
}

View File

@ -1,273 +0,0 @@
//
// Graphics module
//
%module gifplot
%{
#include "gifplot.h"
%}
/* Pixel is 8-bits */
typedef unsigned char Pixel;
typedef float Zvalue;
%disabledoc
/* ------------------------------------------------------------------------
ColorMap
Definition and methods for colormaps
------------------------------------------------------------------------ */
typedef struct ColorMap {
char *name;
//
// %addmethods adds some C methods to this structure to make it
// look like a C++ class in Python.
// These are really named things like ColorMap_default, ColorMap_assign, etc...
%addmethods {
ColorMap(char *filename);
~ColorMap();
#ifdef SWIGJAVA
%name(make_default) void default();
#else
void default();
#endif
void assign(int index,int r, int g, int b);
%name(__getitem__) int getitem(int index);
%name(__setitem__) void setitem(int index, int value);
int write(char *filename);
}
} ColorMap;
/* Some default colors */
#ifdef SWIGJAVA
const Pixel BLACK = 0;
const Pixel WHITE = 1;
const Pixel RED = 2;
const Pixel GREEN = 3;
const Pixel BLUE = 4;
const Pixel YELLOW = 5;
const Pixel CYAN = 6;
const Pixel MAGENTA = 7;
#else
#define BLACK 0
#define WHITE 1
#define RED 2
#define GREEN 3
#define BLUE 4
#define YELLOW 5
#define CYAN 6
#define MAGENTA 7
#endif
/*-------------------------------------------------------------------------
FrameBuffer
This structure defines a simple 8 bit framebuffer.
------------------------------------------------------------------------- */
typedef struct FrameBuffer {
unsigned int height;
unsigned int width;
int xmin; /* These are used for clipping */
int ymin;
int xmax;
int ymax;
%addmethods {
FrameBuffer(unsigned int width, unsigned int height);
~FrameBuffer();
void resize(int width, int height);
void clear(Pixel color);
void plot(int x, int y, Pixel color);
void horizontal(int xmin, int xmax, int y, Pixel color);
void horizontalinterp(int xmin, int xmax, int y, Pixel c1, Pixel c2);
void vertical(int ymin, int ymax, int x, Pixel color);
void box(int x1, int y1, int x2, int y2, Pixel color);
void solidbox(int x1, int y1, int x2, int y2, Pixel color);
void interpbox(int x1, int y1, int x2, int y2, Pixel c1, Pixel c2, Pixel c3, Pixel c4);
void circle(int x1, int y1, int radius, Pixel color);
void solidcircle(int x1, int y1, int radius, Pixel color);
void line(int x1, int y1, int x2, int y2, Pixel color);
void setclip(int xmin, int ymin, int xmax, int ymax);
void noclip();
int makeGIF(ColorMap *cmap, void *buffer, unsigned int maxsize);
void zresize(int width, int height);
void zclear();
void drawchar(int x, int y, int fgcolor, int bgcolor, char chr, int orientation);
void drawstring(int x, int y, int fgcolor, int bgcolor, char *text, int orientation);
void drawpixmap(PixMap *pm, int x, int y, int fgcolor, int bgcolor);
int writeGIF(ColorMap *cmap, char *filename);
}
} FrameBuffer;
#define HORIZONTAL 1
#define VERTICAL 2
/* --------------------------------------------------------------------------
PixMap
The equivalent of "bit-maps".
-------------------------------------------------------------------------- */
/* PIXMAP methods */
extern PixMap *new_PixMap(int width, int height, int centerx, int centery);
extern void delete_PixMap(PixMap *pm);
extern void PixMap_set(PixMap *pm, int x, int y, int pix);
#define TRANSPARENT 0
#define FOREGROUND 1
#define BACKGROUND 2
/* --------------------------------------------------------------------------
Plot2D
Definition and methods for 2D plots.
--------------------------------------------------------------------------- */
typedef struct Plot2D {
FrameBuffer *frame;
int view_xmin; /* Minimum coordinates of view region */
int view_ymin;
int view_xmax; /* Maximum coordinates of view region */
int view_ymax;
double xmin; /* Minimum coordinates of plot region */
double ymin;
double xmax; /* Maximum coordinates of plot region */
double ymax;
int xscale; /* Type of scaling (LINEAR, LOG, etc..) */
int yscale;
%addmethods {
Plot2D(FrameBuffer *frame,double xmin,double ymin, double xmax, double ymax);
~Plot2D();
Plot2D *copy();
void clear(Pixel c);
void setview(int vxmin, int vymin, int vxmax, int vymax);
void setrange(double xmin, double ymin, double xmax, double ymax);
void setscale(int xscale, int yscale);
void plot(double x, double y, Pixel color);
void box(double x1, double y1, double x2, double y2, Pixel color);
void solidbox(double x1, double y1, double x2, double y2, Pixel color);
void interpbox(double x1, double y1, double x2, double y2, Pixel c1, Pixel c2, Pixel c3, Pixel c4);
void circle(double x, double y, double radius, Pixel color);
void solidcircle(double x, double y, double radius, Pixel color);
void line(double x1, double y1, double x2, double y2, Pixel color);
void start();
void drawpixmap(PixMap *pm, double x, double y, Pixel color, Pixel bgcolor);
void xaxis(double x, double y, double xtick, int ticklength, Pixel color);
void yaxis(double x, double y, double ytick, int ticklength, Pixel color);
void triangle(double x1, double y1, double x2, double y2, double x3, double y3, Pixel c);
void solidtriangle(double x1, double y1, double x2, double y2, double x3, double y3, Pixel c);
void interptriangle(double x1, double y1, Pixel c1,
double x2, double y2, Pixel c2,
double x3, double y3, Pixel c3);
}
} Plot2D;
#define LINEAR 10
#define LOG 11
/* ------------------------------------------------------------------------------
Plot3D
Data Structure for 3-D plots
------------------------------------------------------------------------------ */
typedef struct Plot3D {
FrameBuffer *frame;
int view_xmin; /* Viewing region */
int view_ymin;
int view_xmax;
int view_ymax;
double xmin; /* Bounding box */
double ymin;
double zmin;
double xmax;
double ymax;
double zmax;
double xcenter; /* Center point */
double ycenter;
double zcenter;
double fovy; /* Field of view */
double aspect; /* Aspect ratio */
double znear; /* near "clipping" plane */
double zfar; /* far "clipping" plane */
double lookatz; /* Where is the z-lookat point */
double xshift; /* Used for translation and stuff */
double yshift;
%addmethods {
Plot3D(FrameBuffer *frame, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax);
~Plot3D();
Plot3D *copy();
void clear(Pixel bgcolor);
void perspective( double fovy, double znear, double zfar);
void lookat( double z);
void autoperspective( double fovy);
void ortho(double left, double right, double bottom, double top);
void autoortho();
void rotx( double deg);
void roty( double deg);
void rotz( double deg);
void rotl( double deg);
void rotr( double deg);
void rotd( double deg);
void rotu( double deg);
void rotc( double deg);
void zoom( double percent);
void left( double percent);
void right( double percent);
void down( double percent);
void up( double percent);
void center( double cx, double cy);
void plot( double x, double y, double z, Pixel Color);
void setview( int vxmin, int vymin, int vxmax, int vymax);
void start();
void line( double x1, double y1, double z1,
double x2, double y2, double z2, Pixel color);
void triangle( double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3, Pixel color);
void solidtriangle( double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3, Pixel color);
void interptriangle(double x1, double y1, double z1, Pixel c1,
double x2, double y2, double z2, Pixel c2,
double x3, double y3, double z3, Pixel c3);
void quad( double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3,
double x4, double y4, double z4,
Pixel color);
void solidquad( double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3,
double x4, double y4, double z4,
Pixel color);
void interpquad( double x1, double y1, double z1, Pixel c1,
double x2, double y2, double z2, Pixel c2,
double x3, double y3, double z3, Pixel c3,
double x4, double y4, double z4, Pixel c4);
void solidsphere( double x, double y, double z, double radius,Pixel c);
void outlinesphere( double x, double y, double z, double radius,Pixel c, Pixel bc);
}
} Plot3D;
#ifndef SWIGJAVA
const PixMap *SQUARE = &PixMap_SQUARE;
const PixMap *TRIANGLE = &PixMap_TRIANGLE;
const PixMap *CROSS = &PixMap_CROSS;
#endif
%enabledoc

View File

@ -1,107 +0,0 @@
import gifplot;
public class ortho {
static {
System.loadLibrary("jgifplot");
};
public static double func(double x, double y) {
double r;
double f;
r = Math.sqrt(x*x + y*y);
f = (Math.sin(0.30*r*x)+Math.cos(0.30*r*y))/(1.0+r);
return f;
}
public static void main(String argv[]) {
FrameBuffer f;
Plot3D p3;
ColorMap cm;
double x,y;
double dx,dy;
double z1,z2,z3,z4;
int c1,c2,c3,c4;
/* Create a framebuffer */
f = new FrameBuffer(700,400);
/* Load a colormap */
cm = new ColorMap("cm15");
/* Create a new 2D image */
f.clear(gifplot.BLACK);
p3 = new Plot3D(f,-6.3,-6.3,-1.5,6.3,6.3,1.5);
/* Set viewing region in 2D plot */
p3.setview(50,50,650,350);
/* Set how far away from the image we are */
p3.lookat(20);
/* Set the field of view for the perspective */
// Plot3D_autoperspective(p3,40);
p3.autoortho();
/* Now make a plot of a 3D function */
/* Make a frame */
f.noclip();
f.box(49,49,650,350,gifplot.WHITE);
p3.start(); /* Always call this prior to making an image */
p3.clear(gifplot.BLACK);
p3.rotu(60);
p3.rotz(40);
x = -6.3;
dx = 0.25;
while (x < 6.3) {
y = -6.3;
dy = 0.25;
while (y < 6.3) {
z1 = func(x,y);
z2 = func(x+dx,y);
z3 = func(x+dx,y+dy);
z4 = func(x,y+dy);
c1 = (int) ((z1 + 1.0)*120) + 16;
if (c1 < 16) c1 = 16;
if (c1 > 254) c1 = 254;
c2 = (int) ((z2 + 1.0)*120) + 16;
if (c2 < 16) c2 = 16;
if (c2 > 254) c2 = 254;
c3 = (int) ((z3 + 1.0)*120) + 16;
if (c3 < 16) c3 = 16;
if (c3 > 254) c3 = 254;
c4 = (int) ((z4 + 1.0)*120) + 16;
if (c4 < 16) c4 = 16;
if (c4 > 254) c4= 254;
p3.interpquad(x,y,z1,(byte) c1,
x+dx,y,z2,(byte) c2,
x+dx,y+dy,z3,(byte) c3,
x,y+dy,z4,(byte) c4);
y = y + dy;
}
x = x + dx;
}
/* Make a GIF file */
f.writeGIF(cm,"plot.gif");
System.out.println("Image written to 'plot.gif'");
}
}

View File

@ -1,22 +0,0 @@
import gifplot;
public class shadow {
static {
System.loadLibrary("jgifplot");
}
public static void main(String argv[]) {
FrameBuffer fb = new FrameBuffer(300, 300);
ColorMap cm = new ColorMap("cmap");
fb.clear(gifplot.BLACK);
fb.drawstring(50, 50, gifplot.WHITE, gifplot.BLACK, "Hello world", gifplot.VERTICAL);
fb.solidbox(200, 200, 220, 240, gifplot.BLUE);
fb.line(0, 290, 293, 50, gifplot.RED);
fb.circle(100, 100, 10, gifplot.YELLOW);
fb.writeGIF(cm, "plot.gif");
System.out.println("Image written to 'plot.gif'");
}
}

View File

@ -0,0 +1,7 @@
*.class
*.java
*_wrap.c
*_wrap.cxx
*.so
*.dll
*.gif

View File

@ -0,0 +1,20 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -I../../Interface
SRCS =
TARGET = gifplot
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot
INCLUDES = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java
javac *.java
clean::
$(MAKE) -f $(TOP)/Makefile java_clean
rm -f *.gif
check: all

View File

@ -0,0 +1,5 @@
This example uses the file in ../../Interface/gifplot.i to build
an interface with shadow classes. After doing a make, run the program main, ie: 'java main'.
Note the differences in the main.java files between this example and the
'full' example. This example uses the shadow classes.

Binary file not shown.

View File

@ -0,0 +1,76 @@
// Plot a 3D function
import java.lang.Math;
public class main {
static {
try {
System.loadLibrary("gifplot");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
// Here are some plotting parameters
double xmin = -5.0;
double xmax = 5.0;
double ymin = -5.0;
double ymax = 5.0;
double zmin = -5.0;
double zmax = 5.0;
// Grid resolution
int nxpoints = 60;
int nypoints = 60;
ColorMap cmap = new ColorMap("cmap");
FrameBuffer frame = new FrameBuffer(500,500);
frame.clear((short)gifplot.BLACK);
Plot3D p3 = new Plot3D(frame,xmin,ymin,zmin,xmax,ymax,zmax);
p3.lookat(2*(zmax-zmin));
p3.autoperspective(40);
p3.rotu(60);
p3.rotr(30);
p3.rotd(10);
System.out.println( "Making a nice 3D plot..." );
p3.clear((short)gifplot.BLACK);
p3.start();
double dx = 1.0*(xmax-xmin)/nxpoints;
double dy = 1.0*(ymax-ymin)/nypoints;
double cscale = 240.0/(zmax-zmin);
double x = xmin;
for (int i = 0; i < nxpoints; i++) {
double y = ymin;
for (int j = 0; j < nypoints; j++) {
double z1 = func(x,y);
double z2 = func(x+dx,y);
double z3 = func(x+dx,y+dy);
double z4 = func(x,y+dy);
double c1 = cscale*(z1-zmin);
double c2 = cscale*(z2-zmin);
double c3 = cscale*(z3-zmin);
double c4 = cscale*(z4-zmin);
double c = (c1+c2+c3+c4)/4;
if (c < 0) c = 0;
if (c > 239) c = 239;
p3.solidquad(x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,(short)(c+16));
y = y + dy;
}
x = x + dx;
}
frame.writeGIF(cmap,"image.gif");
System.out.println( "Wrote image.gif" );
}
// Here is the function to plot
public static double func(double x, double y) {
return 5*java.lang.Math.cos(2*java.lang.Math.sqrt(x*x+y*y))*java.lang.Math.exp(-0.3*java.lang.Math.sqrt(x*x+y*y));
}
}

View File

@ -1,22 +0,0 @@
import gifplot;
public class simple {
static {
System.loadLibrary("jgifplot");
}
public static void main(String argv[]) {
long f = gifplot.new_FrameBuffer(300, 300);
long c = gifplot.new_ColorMap("cmap");
gifplot.FrameBuffer_clear(f, gifplot.BLACK);
gifplot.FrameBuffer_drawstring(f, 50, 50, gifplot.WHITE, gifplot.BLACK, "Hello world", gifplot.HORIZONTAL);
gifplot.FrameBuffer_solidbox(f, 200, 200, 220, 240, gifplot.BLUE);
gifplot.FrameBuffer_line(f, 0, 290, 293, 50, gifplot.RED);
gifplot.FrameBuffer_circle(f, 100, 100, 10, gifplot.YELLOW);
gifplot.FrameBuffer_writeGIF(f, c, "plot.gif");
System.out.println("Image written to 'plot.gif'");
}
}

View File

@ -0,0 +1,7 @@
*.class
*.java
*_wrap.c
*_wrap.cxx
*.so
*.dll
*.gif

View File

@ -0,0 +1,21 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -noproxy
SRCS =
TARGET = simple
INTERFACE = simple.i
LIBS = -L../.. -lgifplot
INCLUDES = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java
javac *.java
clean::
$(MAKE) -f $(TOP)/Makefile java_clean
rm -f *.gif
check: all

View File

@ -0,0 +1,5 @@
This is a very minimalistic example in which just a few functions
and constants from library are wrapped and used to draw some simple
shapes. After doing a make, run the java program, ie 'java main'.

View File

@ -0,0 +1,41 @@
public class main {
static {
try {
System.loadLibrary("simple");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
// Draw some simple shapes
System.out.println( "Drawing some basic shapes" );
SWIGTYPE_p_ColorMap cmap = simple.new_ColorMap(null);
SWIGTYPE_p_FrameBuffer f = simple.new_FrameBuffer(400,400);
// Clear the picture
simple.FrameBuffer_clear(f,(short)simple.BLACK);
// Make a red box
simple.FrameBuffer_box(f,40,40,200,200,(short)simple.RED);
// Make a blue circle
simple.FrameBuffer_circle(f,200,200,40,(short)simple.BLUE);
// Make green line
simple.FrameBuffer_line(f,10,390,390,200, (short)simple.GREEN);
// Write an image out to disk
simple.FrameBuffer_writeGIF(f,cmap,"image.gif");
System.out.println( "Wrote image.gif" );
simple.delete_FrameBuffer(f);
simple.delete_ColorMap(cmap);
}
}

View File

@ -0,0 +1,38 @@
/* This example shows a very simple interface wrapping a few
primitive declarations */
%module simple
%{
#include "gifplot.h"
%}
typedef unsigned char Pixel;
/* Here are a few useful functions */
ColorMap *new_ColorMap(char *filename = 0);
void delete_ColorMap(ColorMap *cmap);
FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height);
void delete_FrameBuffer(FrameBuffer *frame);
void FrameBuffer_clear(FrameBuffer *frame, Pixel color);
void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color);
int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename);
/* And some useful constants */
#define BLACK 0
#define WHITE 1
#define RED 2
#define GREEN 3
#define BLUE 4
#define YELLOW 5
#define CYAN 6
#define MAGENTA 7

View File

@ -1,41 +0,0 @@
/**********************************************************************
* GIFPlot 0.0
*
* Dave Beazley
*
* Department of Computer Science Theoretical Division (T-11)
* University of Utah Los Alamos National Laboratory
* Salt Lake City, Utah 84112 Los Alamos, New Mexico 87545
* beazley@cs.utah.edu beazley@lanl.gov
*
* Copyright (c) 1996
* The Regents of the University of California and the University of Utah
* All Rights Reserved
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that
* (1) The above copyright notice and the following two paragraphs
* appear in all copies of the source code and (2) redistributions
* including binaries reproduces these notices in the supporting
* documentation. Substantial modifications to this software may be
* copyrighted by their authors and need not follow the licensing terms
* described here, provided that the new terms are clearly indicated in
* all files where they apply.
*
* IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE
* UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
* EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH
* SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
* THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
**************************************************************************/

View File

@ -0,0 +1 @@
Makefile

View File

@ -1,14 +1,14 @@
CC = @CC@
INCLUDE = -I../Include
INCLUDES= -I../Include
CFLAGS = -O
SRCS = frame.c color.c plot2d.c plot3d.c font.c pixmap.c matrix.c gif.c
OBJS = $(SRCS:.c=.o)
OBJS = $(SRCS:.c=.@OBJEXT@)
AR = @AR@
RANLIB = @RANLIB@
TARGET = ../libgifplot.a
.c.o:
$(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
.c.@OBJEXT@:
$(CC) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $<
all: $(OBJS)
@rm -f ../libgifplot.a
@ -16,6 +16,6 @@ all: $(OBJS)
$(RANLIB) $(TARGET)
clean:
rm -f *.o *~ $(TARGET)
rm -f *.@OBJEXT@ *~ $(TARGET)
check: all

View File

@ -99,10 +99,10 @@ FrameBuffer_drawpixmap(FrameBuffer *f, PixMap *pm, int x, int y, int fgcolor, in
for (i = startx; i < endx; i++) {
c = pm->map[py*pm->width + px];
switch (c) {
case FOREGROUND:
case GIFPLOT_FOREGROUND:
f->pixels[j][i] = fgcolor;
break;
case BACKGROUND:
case GIFPLOT_BACKGROUND:
f->pixels[j][i] = bgcolor;
break;
default:

View File

@ -16,8 +16,8 @@ install:
$(RANLIB) $(exec_prefix)/lib/libgifplot.a
clean::
rm -f *.o *~ libgifplot.a *_wrap* *_man*
rm -f *.@OBJEXT@ *~ libgifplot.a *_wrap* *_man*
cd Lib; $(MAKE) clean
rm -f config.log config.status config.cache
check: all

View File

@ -0,0 +1,3 @@
# see top-level Makefile.in
full
simple

View File

@ -0,0 +1,26 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -I../../Include
SRCS =
TARGET = gifcaml
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot -lm
INCLUDES = -I../../Include
MLFILE = gifplot.ml
IOBJS = runme.cmo
PROGFILE = runme.ml
all:: static
static::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static
clean::
$(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean
rm -f *.gif
check: all

View File

@ -0,0 +1,8 @@
This example runs the entire gifplot.h header file through SWIG without
any changes. The ocaml program 'runme.ml' does something a little more
interesting. You'll have to go look at the header file to get a complete
listing of the functions.

Binary file not shown.

View File

@ -0,0 +1,15 @@
/* Oh what the heck, let's just grab the whole darn header file
and see what happens. */
%module gifplot
%{
/* Note: You still need this part because the %include directive
merely causes SWIG to interpret the contents of a file. It doesn't
include the right include headers for the resulting C code */
#include "gifplot.h"
%}
typedef int Pixel;
%include gifplot.h

View File

@ -0,0 +1,86 @@
(* Plot a 3D Function *)
(* Use the wrapped GIFPlot library *)
open Gifplot
open Int32
(* Here is the function to plot *)
let func x y =
5.0 *.
(cos (2.0 *. (sqrt (x *. x) +. (y *. y)))) *.
(exp (-0.3 *. (sqrt (x *. x) +. (y *. y))))
(* Here are some plotting parameters *)
let xmin = -5.0
let xmax = 5.0
let ymin = -5.0
let ymax = 5.0
let zmin = -5.0
let zmax = 5.0
(* Grid resolution *)
let nxpoints = 60
let nypoints = 60
let cmap = _new_ColorMap (C_string "cmap")
let frame = _new_FrameBuffer (C_list [ C_int 500 ;
C_int 500 ])
let _ = _FrameBuffer_clear (C_list [ frame ; _BLACK ])
let p2 = _new_Plot3D (C_list [ frame ;
C_float xmin ; C_float ymin ; C_float zmin ;
C_float xmax ; C_float ymax ; C_float zmax ])
let _ = _Plot3D_lookat (C_list [ p2 ; C_float (2.0 *. (zmax -. zmin)) ])
let _ = _Plot3D_autoperspective (C_list [ p2 ; C_float 40.0 ])
let _ = _Plot3D_rotu (C_list [ p2 ; C_float 60.0 ])
let _ = _Plot3D_rotr (C_list [ p2 ; C_float 30.0 ])
let _ = _Plot3D_rotd (C_list [ p2 ; C_float 10.0 ])
let drawsolid () =
begin
_Plot3D_clear (C_list [ p2 ; _BLACK ]) ;
_Plot3D_start p2 ;
let dx = ((xmax -. xmin) /. (float_of_int nxpoints))
and dy = ((ymax -. ymin) /. (float_of_int nypoints))
and cscale = (240.0 /. (zmax -. zmin)) in
let rec x_loop x i =
if i < nxpoints then
begin
let rec y_loop y j =
begin
if j < nypoints then
let z1 = func x y
and z2 = func (x +. dx) y
and z3 = func (x +. dx) (y +. dy)
and z4 = func x (y +. dy) in
let c1 = cscale *. (z1 -. zmin)
and c2 = cscale *. (z2 -. zmin)
and c3 = cscale *. (z3 -. zmin)
and c4 = cscale *. (z4 -. zmin) in
let cc = (c1 +. c2 +. c3 +. c4) /. 4.0 in
let c = (max (min (int_of_float cc) 239) 0) in
_Plot3D_solidquad
(C_list (p2 ::
(List.map
(fun x -> C_float x)
[ x ; y ; z1 ;
(x +. dx) ; y ; z2 ;
(x +. dx) ; (y +. dy) ; z3 ;
x ; (y +. dx) ; z4 ;
(float_of_int (c + 16)) ]))) ;
y_loop (y +. dy) (j + 1)
end in
begin
y_loop ymin 0 ;
x_loop (x +. dx) (i + 1)
end
end in
x_loop xmin 0
end
let _ = print_endline "Making a nice 3D plot..."
let _ = drawsolid ()
let _ = _FrameBuffer_writeGIF (C_list [ frame ; cmap ; C_string "image.gif" ])
let _ = print_endline "Write image.gif"

View File

@ -0,0 +1,26 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -I../../Include
SRCS =
TARGET = gifsimple
INTERFACE = simple.i
LIBS = -L../.. -lgifplot -lm
INCLUDES = -I../../Include
MLFILE = simple.ml
IOBJS = simple_wrap.o simple.cmo runme.cmo
PROGFILE = runme.ml
all:: static
static::
$(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \
SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static
clean::
$(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean
rm -f *.gif
check: all

Binary file not shown.

View File

@ -0,0 +1,34 @@
(* Draw some simple shapes *)
(* Use the wrapped GIFPlot library *)
open Simple
open Int32
let _ = print_endline "Drawing some basic shapes"
let cmap = _new_ColorMap (C_string "cmap")
let f = _new_FrameBuffer (C_list [ C_int 400 ; C_int 400 ])
(* Clear the picture *)
let _ = _FrameBuffer_clear (C_list [ f ; _BLACK ])
(* Make a red box *)
let _ = _FrameBuffer_box
(C_list [ f ; C_int 40 ; C_int 40 ; C_int 200 ; C_int 200 ; _RED ])
(* Make a blue circle *)
let _ = _FrameBuffer_circle
(C_list [ f ; C_int 200 ; C_int 200 ; C_int 40 ; _BLUE ])
(* Make green line *)
let _ = _FrameBuffer_line
(C_list [ f ; C_int 10 ; C_int 390 ; C_int 390 ; C_int 200 ; _GREEN ])
(* Write an image out to disk *)
let _ = _FrameBuffer_writeGIF (C_list [ f ; cmap ; C_string "image.gif" ])
let _ = print_endline "Wrote image.gif"
let _ = _delete_FrameBuffer f
let _ = _delete_ColorMap cmap

View File

@ -0,0 +1,33 @@
/* This example shows a very simple interface wrapping a few
primitive declarations */
%module simple
%{
#include "gifplot.h"
%}
typedef int Pixel;
/* Here are a few useful functions */
ColorMap *new_ColorMap(char *filename = 0);
void delete_ColorMap(ColorMap *cmap);
FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height);
void delete_FrameBuffer(FrameBuffer *frame);
void FrameBuffer_clear(FrameBuffer *frame, Pixel color);
void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color);
int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename);
/* And some useful constants */
#define BLACK 0
#define WHITE 1
#define RED 2
#define GREEN 3
#define BLUE 4
#define YELLOW 5
#define CYAN 6
#define MAGENTA 7

View File

@ -0,0 +1,4 @@
# see top-level Makefile.in
full
shadow
simple

View File

@ -0,0 +1,5 @@
gifplot.pm
gifplot_wrap.c
*.so
*.dll
*.gif

View File

@ -5,19 +5,20 @@ SRCS =
TARGET = gifplot
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot -lm
INCLUDE = -I../../Include
INCLUDES = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' perl5
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static
clean::
rm -f *_wrap* *.o *~ *.so myperl *.pm .~* core *.gif
$(MAKE) -f $(TOP)/Makefile perl5_clean
rm -f *.gif
check: all

Some files were not shown because too many files have changed in this diff Show More