mirror of https://github.com/swig/swig
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:
parent
5fcae5eb66
commit
12a43edc2d
|
@ -3,3 +3,6 @@ Makefile
|
|||
swig
|
||||
*.tar.gz
|
||||
configure
|
||||
swig.spec
|
||||
autom4te.cache
|
||||
.gdbinit
|
||||
|
|
95
ANNOUNCE
95
ANNOUNCE
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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
|
|
@ -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>
|
|
@ -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ö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>#<swig struct xyzzy * 0x1234affe></code> Two of
|
||||
them are <code>equal?</code> if and only if they have the same type
|
||||
and value.
|
||||
|
||||
<p>
|
||||
To construct a Scheme object from a C pointer, the wrapper code calls
|
||||
the function <code>SWIG_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>
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
>>> <b>from a import *</b>
|
||||
>>> <b>from b import *</b>
|
||||
>>> <b># Create a new "b"</b>
|
||||
>>> <b>b = new_b()</b>
|
||||
>>> <b># Call a function in the base class</b>
|
||||
...
|
||||
>>> <b>a_foo(b,3)</b>
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: Type error in argument 1 of a_foo. Expected _a_p.
|
||||
>>>
|
||||
</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 => { Real, Float }
|
||||
Real => { double, Float }
|
||||
Float => { double, Real }
|
||||
RealPtr => { Real * }
|
||||
Real * => { 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 => { B, C, E } "B isa A, C isa A, E isa A"
|
||||
B => { C, E } "C isa B, E isa B"
|
||||
C => { E } "E isa C"
|
||||
D => { E } "E isa D"
|
||||
E => { }
|
||||
|
||||
</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>
|
|
@ -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 > 0 (not zero)
|
||||
NEGATIVE Any number < 0 (not zero)
|
||||
NONNEGATIVE Any number >= 0
|
||||
NONPOSITIVE Any number <= 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>
|
|
@ -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->()</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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
@ -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><setjmp.h></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 <setjmp.h>
|
||||
jmp_buf exception_buffer;
|
||||
int exception_status;
|
||||
|
||||
/* File : except.h */
|
||||
#include <setjmp.h>
|
||||
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>
|
||||
>>> from example import *
|
||||
>>> a = malloc(2048)
|
||||
>>> b = malloc(1500000000)
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
MemoryError: Out of memory in malloc
|
||||
>>>
|
||||
</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>
|
|
@ -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>
|
File diff suppressed because it is too large
Load Diff
|
@ -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>#<swig struct xyzzy * 0x1234affe></code> Two of
|
||||
them are <code>equal?</code> if and only if they have the same type
|
||||
and value.
|
||||
|
||||
<p>
|
||||
To construct a Scheme object from a C pointer, the wrapper code calls
|
||||
the function <code>SWIG_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>
|
|
@ -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 <= 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 > <b>swig -tcl example.i</b>
|
||||
unix > <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b>
|
||||
unix > <b>gcc -shared example.o example_wrap.o -o example.so</b>
|
||||
unix > <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 > <b>swig -perl5 example.i</b>
|
||||
unix > <b>gcc -c example.c example_wrap.c \
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
unix> <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
|
||||
unix > <b>perl5.003
|
||||
use example;
|
||||
print example::fact(4), "\n";
|
||||
print example::my_mod(23,7), "\n";
|
||||
print $example::My_variable + 4.5, "\n";
|
||||
<ctrl-d></b>
|
||||
24
|
||||
2
|
||||
7.5
|
||||
unix >
|
||||
</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 > <b>swig -python example.i</b>
|
||||
unix > <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b>
|
||||
unix > <b>gcc -shared example.o example_wrap.o -o _example.so</b>
|
||||
unix > <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.
|
||||
>>> <b>import example</b>
|
||||
>>> <b>example.fact(4)</b>
|
||||
24
|
||||
>>> <b>example.my_mod(23,7)</b>
|
||||
2
|
||||
>>> <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> <b>swig -perl5 -module example example.h</b>
|
||||
unix > <b>gcc -c example.c example_wrap.c \
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
unix> <b>ld -G example.o example_wrap.o -o example.so</b>
|
||||
unix > <b>perl5.003
|
||||
use example;
|
||||
print example::fact(4), "\n";
|
||||
print example::my_mod(23,7), "\n";
|
||||
print $example::My_variable + 4.5, "\n";
|
||||
<ctrl-d></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>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 -> 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 <<
|
||||
and >>, 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 -> c_obj -> 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 *. This
|
||||
should be used for all pointer purposes.</li>
|
||||
<li>caml_long_val receives a c_obj and returns a long. 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. This enables out typemaps and inout typemaps
|
||||
to work well. 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>
|
||||
|
||||
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 ] -> C_int 3), and a list
|
||||
containing more than one item is wrapped in C_list (i.e. [ C_char
|
||||
'a' ; C_char 'b' -> C_list [ C_char 'a' ; C_char b
|
||||
]). This is in order to make return values easier to handle
|
||||
when functions have only one return value, such as constructors,
|
||||
and operators. 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. 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. 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. Other than that, correct uses of enums will not have
|
||||
a problem. 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 -> int -> c_obj
|
||||
val enum_to_int c_enum_type -> c_obj -> 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 -> c_obj -> c_obj) wrapped closures. 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 "&" method. 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. 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>"&"</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 <qapplication.h>
|
||||
#include <qpushbutton.h>
|
||||
%}
|
||||
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>
|
File diff suppressed because it is too large
Load Diff
|
@ -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>-></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>
|
|
@ -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ö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>
|
|
@ -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>
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 <= 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->result = "wrong # args";
|
||||
return TCL_ERROR;
|
||||
}
|
||||
arg0 = atoi(argv[1]);
|
||||
result = fact(arg0);
|
||||
sprintf(interp->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>>>> v = Vector()
|
||||
>>> v.x = 3
|
||||
>>> v.y = 4
|
||||
>>> v.z = -13
|
||||
>>> ...
|
||||
>>> del v
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Similarly, in Perl5 you may want the interface to work like this:<p>
|
||||
|
||||
<blockquote><pre>
|
||||
$v = new Vector;
|
||||
$v->{x} = 3;
|
||||
$v->{y} = 4;
|
||||
$v->{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>>>> import graph
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", 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:
|
||||
>>>
|
||||
</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>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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><stdarg.h></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 < 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 < 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 < 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 <= 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 < 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 < 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>
|
|
@ -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& ignored.
|
||||
<li>359. operator| ignored.
|
||||
<li>360. operator~ ignored.
|
||||
<li>361. operator! ignored.
|
||||
<li>362. operator= ignored.
|
||||
<li>363. operator< ignored.
|
||||
<li>364. operator> 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<< ignored.
|
||||
<li>374. operator>>ignored.
|
||||
<li>375. operator<<= ignored.
|
||||
<li>376. operator>>= ignored.
|
||||
<li>377. operator== ignored.
|
||||
<li>378. operator!= ignored.
|
||||
<li>379. operator<= ignored.
|
||||
<li>380. operator>= ignored.
|
||||
<li>381. operator&& ignored.
|
||||
<li>382. operator|| ignored.
|
||||
<li>383. operator++ ignored.
|
||||
<li>384. operator-- ignored.
|
||||
<li>385. operator, ignored.
|
||||
<li>386. operator-<* ignored.
|
||||
<li>387. operator-< 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& 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>
|
|
@ -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>
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
|
@ -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
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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>
|
||||
"""
|
||||
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -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
|
|
@ -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~%")))
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# see top-level Makefile.in
|
||||
full
|
||||
simple
|
|
@ -0,0 +1,3 @@
|
|||
gifplot-guile
|
||||
gifplot_wrap.c
|
||||
image.gif
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
gifguile
|
||||
image.gif
|
||||
simple-guile
|
||||
simple_wrap.c
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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.
|
|
@ -0,0 +1,4 @@
|
|||
# see top-level Makefile.in
|
||||
full
|
||||
shadow
|
||||
simple
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
*.class
|
||||
*.java
|
||||
*_wrap.c
|
||||
*_wrap.cxx
|
||||
*.so
|
||||
*.dll
|
||||
*.gif
|
|
@ -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
|
|
@ -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.
|
@ -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
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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'");
|
||||
}
|
||||
}
|
|
@ -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'");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
*.class
|
||||
*.java
|
||||
*_wrap.c
|
||||
*_wrap.cxx
|
||||
*.so
|
||||
*.dll
|
||||
*.gif
|
|
@ -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
|
|
@ -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.
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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'");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
*.class
|
||||
*.java
|
||||
*_wrap.c
|
||||
*_wrap.cxx
|
||||
*.so
|
||||
*.dll
|
||||
*.gif
|
|
@ -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
|
|
@ -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'.
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
**************************************************************************/
|
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# see top-level Makefile.in
|
||||
full
|
||||
simple
|
|
@ -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
|
|
@ -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.
|
@ -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
|
|
@ -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"
|
|
@ -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.
|
@ -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
|
||||
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
# see top-level Makefile.in
|
||||
full
|
||||
shadow
|
||||
simple
|
|
@ -0,0 +1,5 @@
|
|||
gifplot.pm
|
||||
gifplot_wrap.c
|
||||
*.so
|
||||
*.dll
|
||||
*.gif
|
|
@ -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
Loading…
Reference in New Issue