mirror of https://github.com/swig/swig
3366 lines
88 KiB
HTML
3366 lines
88 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>SWIG and Perl5</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Perl5"></a>31 SWIG and Perl5</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Perl5_nn2">Overview</a>
|
|
<li><a href="#Perl5_nn3">Preliminaries</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn4">Getting the right header files</a>
|
|
<li><a href="#Perl5_nn5">Compiling a dynamic module</a>
|
|
<li><a href="#Perl5_nn6">Building a dynamic module with MakeMaker</a>
|
|
<li><a href="#Perl5_nn7">Building a static version of Perl</a>
|
|
<li><a href="#Perl5_nn8">Using the module</a>
|
|
<li><a href="#Perl5_nn9">Compilation problems and compiling with C++</a>
|
|
<li><a href="#Perl5_nn10">Compiling for 64-bit platforms</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn11">Building Perl Extensions under Windows</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn12">Running SWIG from Developer Studio</a>
|
|
<li><a href="#Perl5_nn13">Using other compilers</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn14">The low-level interface</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn15">Functions</a>
|
|
<li><a href="#Perl5_nn16">Global variables</a>
|
|
<li><a href="#Perl5_nn17">Constants</a>
|
|
<li><a href="#Perl5_nn18">Pointers</a>
|
|
<li><a href="#Perl5_nn19">Structures</a>
|
|
<li><a href="#Perl5_nn20">C++ classes</a>
|
|
<li><a href="#Perl5_nn21">C++ classes and type-checking</a>
|
|
<li><a href="#Perl5_nn22">C++ overloaded functions</a>
|
|
<li><a href="#Perl5_nn23">Operators</a>
|
|
<li><a href="#Perl5_nn24">Modules and packages</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn25">Input and output parameters</a>
|
|
<li><a href="#Perl5_nn26">Exception handling</a>
|
|
<li><a href="#Perl5_nn27">Remapping datatypes with typemaps</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn28">A simple typemap example</a>
|
|
<li><a href="#Perl5_nn29">Perl5 typemaps</a>
|
|
<li><a href="#Perl5_nn30">Typemap variables</a>
|
|
<li><a href="#Perl5_nn31">Useful functions</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn32">Typemap Examples</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn33">Converting a Perl5 array to a char **</a>
|
|
<li><a href="#Perl5_nn34">Return values</a>
|
|
<li><a href="#Perl5_nn35">Returning values from arguments</a>
|
|
<li><a href="#Perl5_nn36">Accessing array structure members</a>
|
|
<li><a href="#Perl5_nn37">Turning Perl references into C pointers</a>
|
|
<li><a href="#Perl5_nn38">Pointer handling</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn39">Proxy classes</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn40">Preliminaries</a>
|
|
<li><a href="#Perl5_nn41">Structure and class wrappers</a>
|
|
<li><a href="#Perl5_nn42">Object Ownership</a>
|
|
<li><a href="#Perl5_nn43">Nested Objects</a>
|
|
<li><a href="#Perl5_nn44">Proxy Functions</a>
|
|
<li><a href="#Perl5_nn45">Inheritance</a>
|
|
<li><a href="#Perl5_nn46">Modifying the proxy methods</a>
|
|
</ul>
|
|
<li><a href="#Perl5_nn47">Adding additional Perl code</a>
|
|
<li><a href="#Perl5_directors">Cross language polymorphism</a>
|
|
<ul>
|
|
<li><a href="#Perl5_nn48">Enabling directors</a>
|
|
<li><a href="#Perl5_nn49">Director classes</a>
|
|
<li><a href="#Perl5_nn50">Ownership and object destruction</a>
|
|
<li><a href="#Perl5_nn51">Exception unrolling</a>
|
|
<li><a href="#Perl5_nn52">Overhead and code bloat</a>
|
|
<li><a href="#Perl5_nn53">Typemaps</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
<b>Caution: This chapter is under repair!</b>
|
|
</p>
|
|
|
|
<p>
|
|
This chapter describes SWIG's support of Perl5. Although the Perl5
|
|
module is one of the earliest SWIG modules, it has continued to evolve
|
|
and has been improved greatly with the help of SWIG users. For the
|
|
best results, it is recommended that SWIG be used with Perl 5.8 or
|
|
later. We're no longer testing regularly with older versions, but
|
|
Perl 5.6 seems to mostly work, while older versions don't.
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn2"></a>31.1 Overview</H2>
|
|
|
|
|
|
<p>
|
|
To build Perl extension modules, SWIG uses a layered approach. At
|
|
the lowest level, simple procedural wrappers are generated for
|
|
functions, classes, methods, and other declarations in the input file.
|
|
Then, for structures and classes, an optional collection of Perl
|
|
proxy classes can be generated in order to provide a more natural object oriented Perl
|
|
interface. These proxy classes simply build upon the low-level interface.
|
|
</p>
|
|
|
|
<p>
|
|
In describing the Perl interface, this chapter begins by covering the
|
|
essentials. First, the problem of configuration, compiling,
|
|
and installing Perl modules is discussed. Next, the low-level
|
|
procedural interface is presented. Finally, proxy classes are
|
|
described. Advanced customization features, typemaps, and other
|
|
options are found near the end of the chapter.
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn3"></a>31.2 Preliminaries</H2>
|
|
|
|
|
|
<p>
|
|
To build a Perl5 module, run SWIG using the <tt>-perl</tt> option as
|
|
follows:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -perl example.i
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
This produces two files. The first file, <tt>example_wrap.c</tt>
|
|
contains all of the C code needed to build a Perl5 module. The second
|
|
file, <tt>example.pm</tt> contains supporting Perl code needed to
|
|
properly load the module.
|
|
</p>
|
|
|
|
<p>
|
|
To build the module, you will need to compile the file
|
|
<tt>example_wrap.c</tt> and link it with the rest of your program.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn4"></a>31.2.1 Getting the right header files</H3>
|
|
|
|
|
|
<p>
|
|
In order to compile, SWIG extensions need the following Perl5 header files:</p>
|
|
|
|
<div class="code"><pre>
|
|
#include "Extern.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
</pre></div>
|
|
|
|
<p>
|
|
These are typically located in a directory like this</p>
|
|
|
|
<div class="code"><pre>
|
|
/usr/lib/perl/5.14/CORE
|
|
</pre></div>
|
|
|
|
<p>
|
|
The SWIG configuration script automatically tries to locate this directory so
|
|
that it can compile examples. However, if you need to find out where the directory is
|
|
located, an easy way to find out is to ask Perl itself:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ perl -e 'use Config; print "$Config{archlib}\n";'
|
|
/usr/lib/perl/5.14
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Perl5_nn5"></a>31.2.2 Compiling a dynamic module</H3>
|
|
|
|
|
|
<p>
|
|
The preferred approach to building an extension module is to compile it into
|
|
a shared object file or DLL. Assuming you have code you need to link to in a file called <tt>example.c</tt>,
|
|
you will need to compile your program using commands like this (shown for Linux):
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -perl example.i
|
|
$ gcc -fPIC example.c
|
|
$ gcc -fPIC -c example_wrap.c -I/usr/lib/perl/5.14/CORE -Dbool=char
|
|
$ gcc -shared example.o example_wrap.o -o example.so
|
|
</pre></div>
|
|
|
|
<p>
|
|
The exact compiler options vary from platform to platform.
|
|
SWIG tries to guess the right options when it is installed. Therefore,
|
|
you may want to start with one of the examples in the <tt>SWIG/Examples/perl5</tt>
|
|
directory. If that doesn't work, you will need to read the man-pages for
|
|
your compiler and linker to get the right set of options. You might also
|
|
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for
|
|
additional information.
|
|
</p>
|
|
|
|
<p>
|
|
When linking the module, the name of the shared object file must match the module name used in
|
|
the SWIG interface file. If you used `<tt>%module example</tt>', then
|
|
the target should be named `<tt>example.so</tt>',
|
|
`<tt>example.sl</tt>', or the appropriate dynamic module name on your system.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn6"></a>31.2.3 Building a dynamic module with MakeMaker</H3>
|
|
|
|
|
|
<p>
|
|
It is also possible to use Perl to build dynamically loadable modules
|
|
for you using the MakeMaker utility. To do this, write a Perl
|
|
script such as the following:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# File : Makefile.PL
|
|
use ExtUtils::MakeMaker;
|
|
WriteMakefile(
|
|
`NAME' => `example', # Name of package
|
|
`LIBS' => [`-lm'], # Name of custom libraries
|
|
`OBJECT' => `example.o example_wrap.o' # Object files
|
|
);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Now, to build a module, simply follow these steps:</p>
|
|
|
|
<div class="code"><pre>
|
|
$ perl Makefile.PL
|
|
$ make
|
|
$ make install
|
|
</pre></div>
|
|
|
|
<p>
|
|
If you are planning to distribute a SWIG-generated module, this is
|
|
the preferred approach to compilation. More information about MakeMaker can be
|
|
found in "Programming Perl, 2nd ed." by Larry Wall, Tom Christiansen,
|
|
and Randal Schwartz.</p>
|
|
|
|
<H3><a name="Perl5_nn7"></a>31.2.4 Building a static version of Perl</H3>
|
|
|
|
|
|
<p>
|
|
If you machine does not support dynamic loading or if you've tried to
|
|
use it without success, you can build a new version of the Perl
|
|
interpreter with your SWIG extensions added to it. To build a static
|
|
extension, you first need to invoke SWIG as follows:</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -perl -static example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
By default SWIG includes code for dynamic loading, but the
|
|
<tt>-static</tt> option takes it out.</p>
|
|
|
|
<p>
|
|
Next, you will need to supply a <tt>main()</tt> function that
|
|
initializes your extension and starts the Perl interpreter. While,
|
|
this may sound daunting, SWIG can do this for you automatically as
|
|
follows:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
extern double My_variable;
|
|
extern int fact(int);
|
|
%}
|
|
|
|
// Include code for rebuilding Perl
|
|
%include <perlmain.i>
|
|
</pre></div>
|
|
|
|
<p>
|
|
The same thing can be accomplished by running SWIG as follows:</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -perl -static -lperlmain.i example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>perlmain.i</tt> file inserts Perl's <tt>main()</tt> function
|
|
into the wrapper code and automatically initializes the SWIG generated
|
|
module. If you just want to make a quick a dirty module, this may be
|
|
the easiest way. By default, the <tt>perlmain.i</tt> code does not
|
|
initialize any other Perl extensions. If you need to use other
|
|
packages, you will need to modify it appropriately. You can do this by
|
|
just copying <tt>perlmain.i</tt> out of the SWIG library, placing it
|
|
in your own directory, and modifying it to suit your purposes.</p>
|
|
|
|
<p>
|
|
To build your new Perl executable, follow the exact same procedure as
|
|
for a dynamic module, but change the link line to something like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ gcc example.o example_wrap.o -L/usr/lib/perl/5.14/CORE \
|
|
-lperl -lsocket -lnsl -lm -o myperl
|
|
</pre></div>
|
|
|
|
<p>
|
|
This will produce a new version of Perl called <tt>myperl</tt>. It
|
|
should be functionality identical to Perl with your C/C++ extension
|
|
added to it. Depending on your machine, you may need to link with
|
|
additional libraries such as <tt>-lsocket, -lnsl, -ldl</tt>, etc.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn8"></a>31.2.5 Using the module</H3>
|
|
|
|
|
|
<p>
|
|
To use the module, simply use the Perl <tt>use</tt> statement. If
|
|
all goes well, you will be able to do this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
$ perl
|
|
use example;
|
|
print example::fact(4),"\n";
|
|
24
|
|
</pre></div>
|
|
|
|
<p>
|
|
A common error received by first-time users is the following:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
Can't locate example.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at - line 1.
|
|
BEGIN failed--compilation aborted at - line 1.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This error is almost caused when the name of the shared object file you created doesn't match the module name
|
|
you specified with the <tt>%module</tt> directive.
|
|
</p>
|
|
|
|
<p>
|
|
A somewhat related, but slightly different error is this:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
Can't find 'boot_example' symbol in ./example.so
|
|
at - line 1
|
|
BEGIN failed--compilation aborted at - line 1.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This error is generated because Perl can't locate the module bootstrap function in the
|
|
SWIG extension module. This could be caused by a mismatch between the module name and the shared library name.
|
|
However, another possible cause is forgetting to link the SWIG-generated wrapper code with the rest
|
|
of your application when you linked the extension module.
|
|
</p>
|
|
|
|
<p>
|
|
Another common error is the following:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
Can't load './example.so' for module example: ./example.so:
|
|
undefined symbol: Foo at /usr/lib/perl/5.14/i386-linux/DynaLoader.pm line 169.
|
|
|
|
at - line 1
|
|
BEGIN failed--compilation aborted at - line 1.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This error usually indicates that you forgot to include some object
|
|
files or libraries in the linking of the shared library file. Make
|
|
sure you compile both the SWIG wrapper file and your original program
|
|
into a shared library file. Make sure you pass all of the required libraries
|
|
to the linker.
|
|
</p>
|
|
|
|
<p>
|
|
Sometimes unresolved symbols occur because a wrapper has been created
|
|
for a function that doesn't actually exist in a library. This usually
|
|
occurs when a header file includes a declaration for a function that
|
|
was never actually implemented or it was removed from a library
|
|
without updating the header file. To fix this, you can either edit
|
|
the SWIG input file to remove the offending declaration or you can use
|
|
the <tt>%ignore</tt> directive to ignore the declaration. Better yet,
|
|
update the header file so that it doesn't have an undefined declaration.
|
|
</p>
|
|
|
|
<p>
|
|
Finally, suppose that your extension module is linked with another library like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
|
|
-o example.so
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If the <tt>foo</tt> library is compiled as a shared library, you might get the following
|
|
error when you try to use your module:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
Can't load './example.so' for module example: libfoo.so: cannot open shared object file:
|
|
No such file or directory at /usr/lib/perl/5.14/i386-linux/DynaLoader.pm line 169.
|
|
|
|
at - line 1
|
|
BEGIN failed--compilation aborted at - line 1.
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This error is generated because the dynamic linker can't locate the
|
|
<tt>libfoo.so</tt> library. When shared libraries are loaded, the
|
|
system normally only checks a few standard locations such as
|
|
<tt>/usr/lib</tt> and <tt>/usr/local/lib</tt>. To get the loader to look in other
|
|
locations, there are several things you can do. First, you can recompile your extension
|
|
module with extra path information. For example, on Linux you can do this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
|
|
<b>-Xlinker -rpath /home/beazley/projects/lib \</b>
|
|
-o example.so
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Alternatively, you can set the <tt>LD_LIBRARY_PATH</tt> environment
|
|
variable to include the directory with your shared libraries. If
|
|
setting <tt>LD_LIBRARY_PATH</tt>, be aware that setting this variable
|
|
can introduce a noticeable performance impact on all other
|
|
applications that you run. To set it only for Perl, you might want
|
|
to do this instead:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ env LD_LIBRARY_PATH=/home/beazley/projects/lib perl
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Finally, you can use a command such as <tt>ldconfig</tt> (Linux) or
|
|
<tt>crle</tt> (Solaris) to add additional search paths to the default
|
|
system configuration (this requires root access and you will need to
|
|
read the man pages).
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn9"></a>31.2.6 Compilation problems and compiling with C++</H3>
|
|
|
|
|
|
<p>
|
|
Compilation of C++ extensions has traditionally been a tricky problem.
|
|
Since the Perl interpreter is written in C, you need to take steps to
|
|
make sure C++ is properly initialized and that modules are compiled
|
|
correctly.
|
|
</p>
|
|
|
|
<p>
|
|
On most machines, C++ extension modules should be linked using the C++
|
|
compiler. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -c++ -perl example.i
|
|
$ g++ -fPIC -c example.cxx
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.14/i386-linux/CORE
|
|
$ <b>g++ -shared example.o example_wrap.o -o example.so</b>
|
|
</pre></div>
|
|
|
|
<p>
|
|
In addition to this, you may need to include additional library
|
|
files to make it work. For example, if you are using the Sun C++ compiler on
|
|
Solaris, you often need to add an extra library <tt>-lCrun</tt> like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -c++ -perl example.i
|
|
$ CC -Kpic -c example.cxx
|
|
$ CC -Kpic -c example_wrap.cxx -I/usr/lib/perl/5.14/i386-linux/CORE
|
|
$ CC -shared example.o example_wrap.o -o example.so <b>-lCrun</b>
|
|
</pre></div>
|
|
|
|
<p>
|
|
Of course, the names of the extra libraries are completely non-portable---you will
|
|
probably need to do some experimentation.
|
|
</p>
|
|
|
|
<p>
|
|
Another possible compile problem comes from recent versions of Perl (5.8.0) and the GNU tools.
|
|
If you see errors having to do with _crypt_struct, that means _GNU_SOURCE is not defined and
|
|
it needs to be. So you should compile the wrapper like:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE -D_GNU_SOURCE
|
|
</pre></div>
|
|
|
|
<p>
|
|
-D_GNU_SOURCE is also included in the Perl ccflags, which can be found by running
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ perl -e 'use Config; print "$Config{ccflags}\n";'
|
|
</pre></div>
|
|
|
|
<p>
|
|
So you could also compile the wrapper like
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \
|
|
`perl -MConfig -e 'print $Config{ccflags}'`
|
|
</pre></div>
|
|
|
|
<p>
|
|
Sometimes people have suggested that it is necessary to relink the
|
|
Perl interpreter using the C++ compiler to make C++ extension modules work.
|
|
In the experience of this author, this has never actually appeared to be
|
|
necessary on most platforms. Relinking the interpreter with C++ really only includes the
|
|
special run-time libraries described above---as long as you link your extension
|
|
modules with these libraries, it should not be necessary to rebuild Perl.
|
|
</p>
|
|
|
|
<p>
|
|
If you aren't entirely sure about the linking of a C++ extension, you
|
|
might look at an existing C++ program. On many Unix machines, the
|
|
<tt>ldd</tt> command will list library dependencies. This should give
|
|
you some clues about what you might have to include when you link your
|
|
extension module. For example, notice the first line of output here:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ ldd swig
|
|
<b>libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)</b>
|
|
libm.so.6 => /lib/libm.so.6 (0x4005b000)
|
|
libc.so.6 => /lib/libc.so.6 (0x40077000)
|
|
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
|
|
$
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If linking wasn't enough of a problem, another major complication of C++ is that it does not
|
|
define any sort of standard for binary linking of libraries. This
|
|
means that C++ code compiled by different compilers will not link
|
|
together properly as libraries nor is the memory layout of classes and
|
|
data structures implemented in any kind of portable manner. In a
|
|
monolithic C++ program, this problem may be unnoticed. However, in Perl, it
|
|
is possible for different extension modules to be compiled with
|
|
different C++ compilers. As long as these modules are self-contained,
|
|
this probably won't matter. However, if these modules start sharing data,
|
|
you will need to take steps to avoid segmentation faults and other
|
|
erratic program behavior. Also, be aware that certain C++ features, especially RTTI,
|
|
can behave strangely when working with multiple modules.
|
|
</p>
|
|
|
|
<p>
|
|
It should be noted that you may get a lot of error messages
|
|
about the '<tt>bool</tt>' datatype when compiling a C++ Perl module. If
|
|
you experience this problem, you can try the following:</p>
|
|
|
|
<ul>
|
|
<li>Use <tt>-DHAS_BOOL</tt> when compiling the SWIG wrapper code
|
|
<li>Or use <tt>-Dbool=char</tt> when compiling.
|
|
</ul>
|
|
|
|
<p>
|
|
Finally, recent versions of Perl (5.8.0) have namespace conflict problems. Perl defines a bunch
|
|
of short macros to make the Perl API function names shorter. For example, in
|
|
/usr/lib/perl/5.8.0/CORE/embed.h there is a line:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
#define do_open Perl_do_open
|
|
</pre></div>
|
|
|
|
<p>
|
|
The problem is, in the <iostream> header from GNU libstdc++v3 there is a private
|
|
function named do_open. If <iostream> is included after the perl headers, then
|
|
the Perl macro causes the iostream do_open to be renamed, which causes compile errors.
|
|
Hopefully in the future Perl will support a PERL_NO_SHORT_NAMES flag, but for now the
|
|
only solution is to undef the macros that conflict. Lib/perl5/noembed.h in the SWIG
|
|
source has a list of macros that are known to conflict with either standard headers or
|
|
other headers. But if you get macro type conflicts from other macros not included
|
|
in Lib/perl5/noembed.h while compiling the wrapper, you will
|
|
have to find the macro that conflicts and add an #undef into the .i file. Please report
|
|
any conflicting macros you find to <a href="http://www.swig.org/mail.html">swig-user mailing list</a>.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn10"></a>31.2.7 Compiling for 64-bit platforms</H3>
|
|
|
|
|
|
<p>
|
|
On platforms that support 64-bit applications (Solaris, Irix, etc.),
|
|
special care is required when building extension modules. On these
|
|
machines, 64-bit applications are compiled and linked using a different
|
|
set of compiler/linker options. In addition, it is not generally possible to mix
|
|
32-bit and 64-bit code together in the same application.
|
|
</p>
|
|
|
|
<p>
|
|
To utilize 64-bits, the Perl executable will need to be recompiled
|
|
as a 64-bit application. In addition, all libraries, wrapper code,
|
|
and every other part of your application will need to be compiled for
|
|
64-bits. If you plan to use other third-party extension modules, they
|
|
will also have to be recompiled as 64-bit extensions.
|
|
</p>
|
|
|
|
<p>
|
|
If you are wrapping commercial software for which you have no source
|
|
code, you will be forced to use the same linking standard as used by
|
|
that software. This may prevent the use of 64-bit extensions. It may
|
|
also introduce problems on platforms that support more than one
|
|
linking standard (e.g., -o32 and -n32 on Irix).
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn11"></a>31.3 Building Perl Extensions under Windows</H2>
|
|
|
|
|
|
<p>
|
|
Building a SWIG extension to Perl under Windows is roughly
|
|
similar to the process used with Unix. Normally, you will want to
|
|
produce a DLL that can be loaded into the Perl interpreter. This
|
|
section assumes you are using SWIG with Microsoft Visual C++
|
|
although the procedure may be similar with other compilers.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn12"></a>31.3.1 Running SWIG from Developer Studio</H3>
|
|
|
|
|
|
<p>
|
|
If you are developing your application within Microsoft developer
|
|
studio, SWIG can be invoked as a custom build option. The process
|
|
roughly requires these steps:</p>
|
|
|
|
<ul>
|
|
<li>Open up a new workspace and use the AppWizard to select a DLL
|
|
project.
|
|
|
|
<li>Add both the SWIG interface file (the .i file), any supporting C
|
|
files, and the name of the wrapper file that will be created by SWIG
|
|
(ie. <tt>example_wrap.c</tt>). Note: If using C++, choose a
|
|
different suffix for the wrapper file such as
|
|
<tt>example_wrap.cxx</tt>. Don't worry if the wrapper file doesn't
|
|
exist yet--Developer studio will keep a reference to it around.
|
|
|
|
<li>Select the SWIG interface file and go to the settings menu. Under
|
|
settings, select the "Custom Build" option.
|
|
|
|
<li>Enter "SWIG" in the description field.
|
|
|
|
<li>Enter "<tt>swig -perl5 -o $(ProjDir)\$(InputName)_wrap.cxx
|
|
$(InputPath)</tt>" in the "Build command(s) field"
|
|
|
|
<li>Enter "<tt>$(ProjDir)\$(InputName)_wrap.c</tt>xx" in the "Output
|
|
files(s) field".
|
|
|
|
<li>Next, select the settings for the entire project and go to
|
|
"C++:Preprocessor". Add the include directories for your Perl 5
|
|
installation under "Additional include directories".
|
|
|
|
<li>Define the symbols WIN32 and MSWIN32 under preprocessor options.
|
|
If using the ActiveWare port, also define the symbol PERL_OBJECT.
|
|
Note that all extensions to the ActiveWare port must be compiled with
|
|
the C++ compiler since Perl has been encapsulated in a C++ class.
|
|
|
|
<li>Finally, select the settings for the entire project and go to
|
|
"Link Options". Add the Perl library file to your link libraries.
|
|
For example "perl.lib". Also, set the name of the output file to
|
|
match the name of your Perl module (ie. example.dll).
|
|
|
|
<li>Build your project.
|
|
</ul>
|
|
|
|
<p>
|
|
Now, assuming you made it this far, SWIG will be automatically invoked when
|
|
you build your project. Any changes made to the interface file will
|
|
result in SWIG being automatically invoked to produce a new version of
|
|
the wrapper file. To run your new Perl extension, simply run Perl and
|
|
use the use command as normal. For example:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
DOS > perl
|
|
use example;
|
|
$a = example::fact(4);
|
|
print "$a\n";
|
|
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn13"></a>31.3.2 Using other compilers</H3>
|
|
|
|
|
|
<p>
|
|
SWIG is known to work with Cygwin and may work with other compilers on Windows.
|
|
For general hints and suggestions refer to the <a href="Windows.html#Windows">Windows</a> chapter.
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn14"></a>31.4 The low-level interface</H2>
|
|
|
|
|
|
<p>
|
|
At its core, the Perl module uses a simple low-level interface
|
|
to C function, variables, constants, and classes. This low-level interface
|
|
can be used to control your application. However, it is also used to
|
|
construct more user-friendly proxy classes as described in the next section.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn15"></a>31.4.1 Functions</H3>
|
|
|
|
|
|
<p>
|
|
C functions are converted into new Perl built-in commands (or
|
|
subroutines). For example:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
%module example
|
|
int fact(int a);
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
Now, in Perl:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use example;
|
|
$a = &example::fact(2);
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn16"></a>31.4.2 Global variables</H3>
|
|
|
|
|
|
<p>
|
|
Global variables are handled using Perl's magic
|
|
variable mechanism. SWIG generates a pair of functions
|
|
that intercept read/write operations and attaches them to a Perl variable with
|
|
the same name as the C global variable. Thus, an interface like this </p>
|
|
|
|
<div class="targetlang"><pre>
|
|
%module example;
|
|
...
|
|
double Spam;
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
is accessed as follows:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use example;
|
|
print $example::Spam,"\n";
|
|
$example::Spam = $example::Spam + 4
|
|
# ... etc ...
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
If a variable is declared as <tt>const</tt>, it is wrapped as a
|
|
read-only variable. Attempts to modify its value will result in an
|
|
error.
|
|
</p>
|
|
|
|
<p>
|
|
To make ordinary variables read-only, you can also use the <tt>%immutable</tt> directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
extern char *path;
|
|
%}
|
|
%immutable;
|
|
extern char *path;
|
|
%mutable;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The <tt>%immutable</tt> directive stays in effect until it is explicitly disabled or cleared using
|
|
<tt>%mutable</tt>.
|
|
See the <a href="SWIG.html#SWIG_readonly_variables">Creating read-only variables</a> section for further details.
|
|
</p>
|
|
|
|
<p>
|
|
It is also possible to tag a specific variable as read-only like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
extern char *path;
|
|
%}
|
|
%immutable path;
|
|
...
|
|
...
|
|
extern char *path; // Declared later in the input
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Perl5_nn17"></a>31.4.3 Constants</H3>
|
|
|
|
|
|
<p>
|
|
By default, constants are wrapped as read-only Perl variables. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
|
|
#define FOO 42
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In Perl:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
print $example::FOO,"\n"; # OK
|
|
$example::FOO = 2; # Error
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Alternatively, if you use swig's <tt>-const</tt> option, constants are wrapped
|
|
such that the leading $ isn't required (by using a constant subroutine), which
|
|
usually gives a more natural Perl interface, for example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
print example::FOO,"\n";
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Perl5_nn18"></a>31.4.4 Pointers</H3>
|
|
|
|
|
|
<p>
|
|
SWIG represents pointers as blessed references. A blessed reference
|
|
is the same as a Perl reference except that it has additional
|
|
information attached to it indicating what kind of reference it
|
|
is. That is, if you have a C declaration like this:</p>
|
|
|
|
<div class="code"><pre>
|
|
Matrix *new_Matrix(int n, int m);
|
|
</pre></div>
|
|
|
|
<p>
|
|
The module returns a value generated as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
$ptr = new_Matrix(int n, int m); # Save pointer return result
|
|
bless $ptr, "p_Matrix"; # Bless it as a pointer to Matrix
|
|
</pre></div>
|
|
|
|
<p>
|
|
SWIG uses the "blessing" to check the datatype of various pointers.
|
|
In the event of a mismatch, an error or warning message is
|
|
generated.</p>
|
|
|
|
<p>
|
|
To check to see if a value is the NULL pointer, use the
|
|
<tt>defined()</tt> command:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
if (defined($ptr)) {
|
|
print "Not a NULL pointer.";
|
|
} else {
|
|
print "Is a NULL pointer.";
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
To create a NULL pointer, you should pass the <tt>undef</tt> value to
|
|
a function.
|
|
</p>
|
|
|
|
<p>
|
|
The "value" of a Perl reference is not the same as the underlying C
|
|
pointer that SWIG wrapper functions return. Suppose that <tt>$a</tt>
|
|
and <tt>$b</tt> are two references that point to the same C object.
|
|
In general, <tt>$a</tt> and <tt>$b</tt> will be different--since they
|
|
are different references. Thus, it is a mistake to check the equality
|
|
of <tt>$a</tt> and <tt>$b</tt> to check the equality of two C
|
|
pointers. The correct method to check equality of C pointers is to
|
|
dereference them as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
if ($$a == $$b) {
|
|
print "a and b point to the same thing in C";
|
|
} else {
|
|
print "a and b point to different objects.";
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
As much as you might be inclined to modify a pointer value directly
|
|
from Perl, don't. Manipulating pointer values is architecture dependent and
|
|
could cause your program to crash. Similarly, don't try to manually cast
|
|
a pointer to a new type by reblessing a pointer. This
|
|
may not work like you expect and it is particularly dangerous when
|
|
casting C++ objects. If you need to cast a pointer or
|
|
change its value, consider writing some helper functions instead. For
|
|
example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%inline %{
|
|
/* C-style cast */
|
|
Bar *FooToBar(Foo *f) {
|
|
return (Bar *) f;
|
|
}
|
|
|
|
/* C++-style cast */
|
|
Foo *BarToFoo(Bar *b) {
|
|
return dynamic_cast<Foo*>(b);
|
|
}
|
|
|
|
Foo *IncrFoo(Foo *f, int i) {
|
|
return f+i;
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Also, if working with C++, you should always try
|
|
to use the new C++ style casts. For example, in the above code, the
|
|
C-style cast may return a bogus result whereas as the C++-style cast will return
|
|
<tt>NULL</tt> if the conversion can't be performed.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility Note:</b> In earlier versions, SWIG tried to preserve the same pointer naming conventions
|
|
as XS and <tt>xsubpp</tt>. Given the advancement of the SWIG typesystem and the growing differences between
|
|
SWIG and XS, this is no longer supported.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn19"></a>31.4.5 Structures</H3>
|
|
|
|
|
|
<p>
|
|
Access to the contents of a structure are provided through a set of low-level
|
|
accessor functions as described in the "SWIG Basics" chapter. For example,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
struct Vector {
|
|
double x,y,z;
|
|
};
|
|
</pre></div>
|
|
|
|
<p>
|
|
gets mapped into the following collection of accessor functions:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
struct Vector *new_Vector();
|
|
void delete_Vector(Vector *v);
|
|
double Vector_x_get(Vector *obj)
|
|
void Vector_x_set(Vector *obj, double x)
|
|
double Vector_y_get(Vector *obj)
|
|
void Vector_y_set(Vector *obj, double y)
|
|
double Vector_z_get(Vector *obj)
|
|
void Vector_z_set(Vector *obj, double z)
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
These functions are then used to access structure data from Perl as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
$v = example::new_Vector();
|
|
print example::Vector_x_get($v),"\n"; # Get x component
|
|
example::Vector_x_set($v,7.8); # Change x component
|
|
</pre></div>
|
|
|
|
<p>
|
|
Similar access is provided for unions and the data members of C++ classes.
|
|
</p>
|
|
|
|
<p>
|
|
<tt>const</tt> members of a structure are read-only. Data members
|
|
can also be forced to be read-only using the <tt>%immutable</tt> directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Foo {
|
|
...
|
|
%immutable;
|
|
int x; /* Read-only members */
|
|
char *name;
|
|
%mutable;
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When <tt>char *</tt> members of a structure are wrapped, the contents are assumed to be
|
|
dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending on whether or not
|
|
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
|
|
released and a new value created. If this is not the behavior you want, you will have to use
|
|
a typemap (described later).
|
|
</p>
|
|
|
|
<p>
|
|
Array members are normally wrapped as read-only. For example,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Foo {
|
|
int x[50];
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
produces a single accessor function like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int *Foo_x_get(Foo *self) {
|
|
return self->x;
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If you want to set an array member, you will need to supply a "memberin" typemap
|
|
described later in this chapter. As a special case, SWIG does generate
|
|
code to set array members of type <tt>char</tt> (allowing you to store a Python
|
|
string in the structure).
|
|
</p>
|
|
|
|
<p>
|
|
When structure members are wrapped, they are handled as pointers. For example,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
struct Foo {
|
|
...
|
|
};
|
|
|
|
struct Bar {
|
|
Foo f;
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
generates accessor functions such as this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Foo *Bar_f_get(Bar *b) {
|
|
return &b->f;
|
|
}
|
|
|
|
void Bar_f_set(Bar *b, Foo *val) {
|
|
b->f = *val;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H3><a name="Perl5_nn20"></a>31.4.6 C++ classes</H3>
|
|
|
|
|
|
<p>
|
|
C++ classes are wrapped by building a set of low level accessor functions.
|
|
Consider the following class:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
class List {
|
|
public:
|
|
List();
|
|
~List();
|
|
int search(char *item);
|
|
void insert(char *item);
|
|
void remove(char *item);
|
|
char *get(int n);
|
|
int length;
|
|
static void print(List *l);
|
|
};
|
|
</pre></div>
|
|
|
|
<p>
|
|
When wrapped by SWIG, the following functions are created:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
List *new_List();
|
|
void delete_List(List *l);
|
|
int List_search(List *l, char *item);
|
|
void List_insert(List *l, char *item);
|
|
void List_remove(List *l, char *item);
|
|
char *List_get(List *l, int n);
|
|
int List_length_get(List *l);
|
|
void List_length_set(List *l, int n);
|
|
void List_print(List *l);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
In Perl, these functions are used in a straightforward manner:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use example;
|
|
$l = example::new_List();
|
|
example::List_insert($l,"Ale");
|
|
example::List_insert($l,"Stout");
|
|
example::List_insert($l,"Lager")
|
|
example::List_print($l)
|
|
Lager
|
|
Stout
|
|
Ale
|
|
print example::List_length_get($l),"\n";
|
|
3
|
|
</pre></div>
|
|
|
|
<p>
|
|
At this low level, C++ objects are really just typed pointers. Member
|
|
functions are accessed by calling a C-like wrapper with an instance pointer
|
|
as the first argument. Although this interface is fairly primitive, it
|
|
provides direct access to C++ objects. A higher level interface using Perl proxy classes
|
|
can be built using these low-level accessors. This is described shortly.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn21"></a>31.4.7 C++ classes and type-checking</H3>
|
|
|
|
|
|
<p>
|
|
The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have
|
|
classes like this
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class Foo {
|
|
...
|
|
};
|
|
|
|
class Bar : public Foo {
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
and a function
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void spam(Foo *f);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
then the function <tt>spam()</tt> accepts <tt>Foo *</tt> or a pointer to any class derived from <tt>Foo</tt>.
|
|
If necessary, the type-checker also adjusts the value of the pointer (as is necessary when
|
|
multiple inheritance is used).
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn22"></a>31.4.8 C++ overloaded functions</H3>
|
|
|
|
|
|
<p>
|
|
If you have a C++ program with overloaded functions or methods, you will need to disambiguate
|
|
those methods using <tt>%rename</tt>. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Forward renaming declarations */
|
|
%rename(foo_i) foo(int);
|
|
%rename(foo_d) foo(double);
|
|
...
|
|
void foo(int); // Becomes 'foo_i'
|
|
void foo(char *c); // Stays 'foo' (not renamed)
|
|
|
|
class Spam {
|
|
public:
|
|
void foo(int); // Becomes 'foo_i'
|
|
void foo(double); // Becomes 'foo_d'
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Now, in Perl, the methods are accessed as follows:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
example::foo_i(3);
|
|
$s = example::new_Spam();
|
|
example::Spam_foo_i($s,3);
|
|
example::Spam_foo_d($s,3.14);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Please refer to the "SWIG Basics" chapter for more information.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn23"></a>31.4.9 Operators</H3>
|
|
|
|
|
|
<p>
|
|
As of version 1.3.27 SWIG automatically renames the most common C++ operators, and maps them into the perl module with the proper 'use overload ...' so you don't need to do any work.
|
|
</p>
|
|
|
|
<p>
|
|
The following C++ operators are currently supported by the Perl module:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>operator++ </li>
|
|
<li>operator-- </li>
|
|
<li>operator+ </li>
|
|
<li>operator- </li>
|
|
<li>operator* </li>
|
|
<li>operator/ </li>
|
|
<li>operator== </li>
|
|
<li>operator!= </li>
|
|
<li>operator% </li>
|
|
<li>operator> </li>
|
|
<li>operator< </li>
|
|
<li>operator and </li>
|
|
<li>operator or </li>
|
|
</ul>
|
|
|
|
<H3><a name="Perl5_nn24"></a>31.4.10 Modules and packages</H3>
|
|
|
|
|
|
<p>
|
|
When you create a SWIG extension, everything gets placed into
|
|
a single Perl module. The name of the module is determined by the
|
|
<tt>%module</tt> directive. To use the module, do the following:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
$ perl5
|
|
use example; # load the example module
|
|
print example::fact(4),"\n" # Call a function in it
|
|
24
|
|
</pre></div>
|
|
|
|
<p>
|
|
Usually, a module consists of a collection of code that is contained
|
|
within a single file. A package, on the other hand, is the Perl
|
|
equivalent of a namespace. A package is a lot like a module, except
|
|
that it is independent of files. Any number of files may be part of
|
|
the same package--or a package may be broken up into a collection of
|
|
modules if you prefer to think about it in this way.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG installs its functions into a package with the same name as
|
|
the module. </p>
|
|
|
|
<p>
|
|
<b>Incompatible Change:</b> previous versions of SWIG enabled you to
|
|
change the name of the package by using the -package option, this
|
|
feature has been removed in order to properly support modules that
|
|
used nested namespaces, e.g. Foo::Bar::Baz. To give your module a
|
|
nested namespace simply provide the fully qualified name in your
|
|
%module directive: </p>
|
|
|
|
<div class="code"><pre>
|
|
%module "Foo::Bar::Baz"
|
|
</pre></div>
|
|
|
|
<p>
|
|
<b>NOTE:</b> the double quotes are necessary.
|
|
</p>
|
|
|
|
<p>
|
|
Using the <tt>package</tt> option of the <tt>%module</tt> directive allows
|
|
you to specify what Perl namespace that the module will be living in when
|
|
installed. This is useful in the situation where a module maintainer
|
|
wants to split a large module into smaller pieces to make maintenance
|
|
easier, but doesn't want to have that affect the module name used by
|
|
applications. So for example, if I wanted to split <tt>XML::Xerces</tt>
|
|
into <tt>XML::Xerces::SAX</tt>, etc. , but I wanted all the applications
|
|
to be able to access the classes using the <tt>XML::Xerces</tt> namespace
|
|
I could use:
|
|
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module(package="XML::Xerces") "XML::Xerces::SAX
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
And now all the applications could use the class
|
|
<tt>XML::Xerces::SAXParser</tt>. Without the <tt>package</tt> directive
|
|
splitting the module would force applications to use the class
|
|
<tt>XML::Xerces::SAX::SAXParser</tt>. This could break compatibility for
|
|
existing applications that are already using the class under the name
|
|
<tt>XML::Xerces::SAXParser</tt>.
|
|
</p>
|
|
|
|
<!--
|
|
<p>
|
|
This can be changed by giving SWIG the -package
|
|
option:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
$ swig -perl -package Foo example.i
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case, you still create a module called `<tt>example</tt>' exactly as before, but
|
|
all of the functions in that module will be installed into the package
|
|
`<tt>Foo</tt>.' For example:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use example; # Load the module like before
|
|
print Foo::fact(4),"\n"; # Call a function in package FooBar
|
|
</pre></div>
|
|
-->
|
|
|
|
<H2><a name="Perl5_nn25"></a>31.5 Input and output parameters</H2>
|
|
|
|
|
|
<p>
|
|
A common problem in some C programs is handling parameters passed as simple pointers. For
|
|
example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void add(int x, int y, int *result) {
|
|
*result = x + y;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
or perhaps
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int sub(int *x, int *y) {
|
|
return *x+*y;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The easiest way to handle these situations is to use the <tt>typemaps.i</tt> file. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "typemaps.i"
|
|
|
|
void add(int, int, int *OUTPUT);
|
|
int sub(int *INPUT, int *INPUT);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In Perl, this allows you to pass simple values. For example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
$a = example::add(3,4);
|
|
print "$a\n";
|
|
7
|
|
$b = example::sub(7,4);
|
|
print "$b\n";
|
|
3
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Notice how the <tt>INPUT</tt> parameters allow integer values to be passed instead of pointers
|
|
and how the <tt>OUTPUT</tt> parameter creates a return result.
|
|
</p>
|
|
|
|
<p>
|
|
If you don't want to use the names <tt>INPUT</tt> or <tt>OUTPUT</tt>, use the <tt>%apply</tt>
|
|
directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "typemaps.i"
|
|
|
|
%apply int *OUTPUT { int *result };
|
|
%apply int *INPUT { int *x, int *y};
|
|
|
|
void add(int x, int y, int *result);
|
|
int sub(int *x, int *y);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If a function mutates one of its parameters like this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void negate(int *x) {
|
|
*x = -(*x);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
you can use <tt>INOUT</tt> like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%include "typemaps.i"
|
|
...
|
|
void negate(int *INOUT);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In Perl, a mutated parameter shows up as a return value. For example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
$a = example::negate(3);
|
|
print "$a\n";
|
|
-3
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The most common use of these special typemap rules is to handle functions that
|
|
return more than one value. For example, sometimes a function returns a result
|
|
as well as a special error code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* send message, return number of bytes sent, along with success code */
|
|
int send_message(char *text, int len, int *success);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To wrap such a function, simply use the <tt>OUTPUT</tt> rule above. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "typemaps.i"
|
|
%apply int *OUTPUT { int *success };
|
|
...
|
|
int send_message(char *text, int *success);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When used in Perl, the function will return multiple values.
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
($bytes, $success) = example::send_message("Hello World");
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Another common use of multiple return values are in query functions. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void get_dimensions(Matrix *m, int *rows, int *columns);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To wrap this, you might use the following:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "typemaps.i"
|
|
%apply int *OUTPUT { int *rows, int *columns };
|
|
...
|
|
void get_dimensions(Matrix *m, int *rows, *columns);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Now, in Perl:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
($r,$c) = example::get_dimensions($m);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In certain cases, it is possible to treat Perl references as C pointers. To do this, use the <tt>REFERENCE</tt> typemap. For
|
|
example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module example
|
|
%include "typemaps.i"
|
|
|
|
void add(int x, int y, int *REFERENCE);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In Perl:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use example;
|
|
$c = 0.0;
|
|
example::add(3,4,\$c);
|
|
print "$c\n";
|
|
7
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Note:</b> The <tt>REFERENCE</tt> feature is only currently supported for numeric types (integers and floating point).
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn26"></a>31.6 Exception handling</H2>
|
|
|
|
|
|
<p>
|
|
The SWIG <tt>%exception</tt> directive can be used to create a
|
|
user-definable exception handler for converting exceptions in your
|
|
C/C++ program into Perl exceptions. The chapter on customization features
|
|
contains more details, but suppose you have a C++ class like the
|
|
following:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
class RangeError {}; // Used for an exception
|
|
|
|
class DoubleArray {
|
|
private:
|
|
int n;
|
|
double *ptr;
|
|
public:
|
|
// Create a new array of fixed size
|
|
DoubleArray(int size) {
|
|
ptr = new double[size];
|
|
n = size;
|
|
}
|
|
// Destroy an array
|
|
~DoubleArray() {
|
|
delete ptr;
|
|
}
|
|
// Return the length of the array
|
|
int length() {
|
|
return n;
|
|
}
|
|
|
|
// Get an item from the array and perform bounds checking.
|
|
double getitem(int i) {
|
|
if ((i >= 0) && (i < n))
|
|
return ptr[i];
|
|
else
|
|
throw RangeError();
|
|
}
|
|
|
|
// Set an item in the array and perform bounds checking.
|
|
void setitem(int i, double val) {
|
|
if ((i >= 0) && (i < n))
|
|
ptr[i] = val;
|
|
else {
|
|
throw RangeError();
|
|
}
|
|
}
|
|
};
|
|
</pre></div>
|
|
|
|
<p>
|
|
Since several methods in this class can throw an exception
|
|
for an out-of-bounds access, you might want to catch
|
|
this in the Perl extension by writing the following in an
|
|
interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%exception {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
croak("Array index out-of-bounds");
|
|
}
|
|
}
|
|
|
|
class DoubleArray {
|
|
...
|
|
};
|
|
</pre></div>
|
|
|
|
<p>
|
|
The exception handling code is inserted directly into generated wrapper
|
|
functions. The <tt>$action</tt> variable is replaced with the C/C++
|
|
code being executed by the wrapper. When an exception handler
|
|
is defined, errors can be caught and used to gracefully generate a Perl error
|
|
instead of forcing the entire program to terminate with an uncaught error.
|
|
</p>
|
|
|
|
<p>
|
|
As shown, the exception handling code will be added to every wrapper function.
|
|
Since this is somewhat inefficient. You might consider refining the
|
|
exception handler to only apply to specific methods like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%exception getitem {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
croak("Array index out-of-bounds");
|
|
}
|
|
}
|
|
|
|
%exception setitem {
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
croak("Array index out-of-bounds");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, the exception handler is only attached to methods and functions
|
|
named <tt>getitem</tt> and <tt>setitem</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
If you had a lot of different methods, you can avoid extra typing by using a macro.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%define RANGE_ERROR
|
|
{
|
|
try {
|
|
$action
|
|
}
|
|
catch (RangeError) {
|
|
croak("Array index out-of-bounds");
|
|
}
|
|
}
|
|
%enddef
|
|
|
|
%exception getitem RANGE_ERROR;
|
|
%exception setitem RANGE_ERROR;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Since SWIG's exception handling is user-definable, you are not limited to C++ exception handling.
|
|
See the chapter on "<a href="Customization.html#Customization">Customization features</a>" for more examples.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Compatibility note:</b> In SWIG1.1, exceptions were defined using the older <tt>%except</tt> directive:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%except(python) {
|
|
try {
|
|
$function
|
|
}
|
|
catch (RangeError) {
|
|
croak("Array index out-of-bounds");
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This is still supported, but it is deprecated. The newer <tt>%exception</tt> directive provides the same
|
|
functionality, but it has additional capabilities that make it more powerful.
|
|
</p>
|
|
|
|
<H2><a name="Perl5_nn27"></a>31.7 Remapping datatypes with typemaps</H2>
|
|
|
|
|
|
<p>
|
|
This section describes how you can modify SWIG's default wrapping behavior
|
|
for various C/C++ datatypes using the <tt>%typemap</tt> directive. This
|
|
is an advanced topic that assumes familiarity with the Perl C API as well
|
|
as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
|
</p>
|
|
|
|
<p>
|
|
Before proceeding, it should be stressed that typemaps are <em>not</em> a required
|
|
part of using SWIG---the default wrapping behavior is enough in most cases.
|
|
Typemaps are only used if you want to change some aspect of the primitive
|
|
C-Perl interface.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn28"></a>31.7.1 A simple typemap example</H3>
|
|
|
|
|
|
<p>
|
|
A typemap is nothing more than a code generation rule that is attached to
|
|
a specific C datatype. For example, to convert integers from Perl to C,
|
|
you might define a typemap like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
%typemap(in) int {
|
|
$1 = (int) SvIV($input);
|
|
printf("Received an integer : %d\n", $1);
|
|
}
|
|
...
|
|
%inline %{
|
|
extern int fact(int n);
|
|
%}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Typemaps are always associated with some specific aspect of code generation.
|
|
In this case, the "in" method refers to the conversion of input arguments
|
|
to C/C++. The datatype <tt>int</tt> is the datatype to which the typemap
|
|
will be applied. The supplied C code is used to convert values. In this
|
|
code a number of special variable prefaced by a <tt>$</tt> are used. The
|
|
<tt>$1</tt> variable is placeholder for a local variable of type <tt>int</tt>.
|
|
The <tt>$input</tt> variable is the input object (usually a <tt>SV *</tt>).
|
|
</p>
|
|
|
|
<p>
|
|
When this example is used in Perl5, it will operate as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use example;
|
|
$n = example::fact(6);
|
|
print "$n\n";
|
|
...
|
|
|
|
Output:
|
|
Received an integer : 6
|
|
720
|
|
</pre></div>
|
|
|
|
<p>
|
|
The application of a typemap to specific datatypes and argument names involves
|
|
more than simple text-matching--typemaps are fully integrated into the
|
|
SWIG type-system. When you define a typemap for <tt>int</tt>, that typemap
|
|
applies to <tt>int</tt> and qualified variations such as <tt>const int</tt>. In addition,
|
|
the typemap system follows <tt>typedef</tt> declarations. For example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
%typemap(in) int n {
|
|
$1 = (int) SvIV($input);
|
|
printf("n = %d\n",$1);
|
|
}
|
|
%inline %{
|
|
typedef int Integer;
|
|
extern int fact(Integer n); // Above typemap is applied
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
It should be noted that the matching of <tt>typedef</tt> only occurs in one direction. If you
|
|
defined a typemap for <tt>Integer</tt>, it is not applied to arguments of
|
|
type <tt>int</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
Typemaps can also be defined for groups of consecutive arguments. For example:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
%typemap(in) (char *str, unsigned len) {
|
|
$1 = SvPV($input,$2);
|
|
};
|
|
|
|
int count(char c, char *str, unsigned len);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When a multi-argument typemap is defined, the arguments are always handled as a single
|
|
Perl object. This allows the function to be used like this (notice how the length
|
|
parameter is omitted):
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
example::count("e","Hello World");
|
|
1
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H3><a name="Perl5_nn29"></a>31.7.2 Perl5 typemaps</H3>
|
|
|
|
|
|
<p>
|
|
The previous section illustrated an "in" typemap for converting Perl objects to C.
|
|
A variety of different typemap methods are defined by the Perl module. For example,
|
|
to convert a C integer back into a Perl object, you might define an "out" typemap
|
|
like this:
|
|
</p>
|
|
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
%typemap(out) int {
|
|
$result = sv_newmortal();
|
|
set_setiv($result, (IV) $1);
|
|
argvi++;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The following typemap methods are available:
|
|
</p>
|
|
|
|
<p>
|
|
<tt>%typemap(in)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts Perl5 object to input function arguments.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(out)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts function return value to a Perl5 value.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(varin)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts a Perl5 object to a global variable.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(varout)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts a global variable to a Perl5 object.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(freearg)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Cleans up a function argument after a function call
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(argout)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Output argument handling
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(ret)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Clean up return value from a function.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(memberin)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Setting of C++ member data (all languages).
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(memberout)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Return of C++ member data (all languages).
|
|
</div>
|
|
|
|
<p>
|
|
<tt>%typemap(check)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Check value of input parameter.
|
|
</div>
|
|
|
|
<H3><a name="Perl5_nn30"></a>31.7.3 Typemap variables</H3>
|
|
|
|
|
|
<p>
|
|
Within typemap code, a number of special variables prefaced with a <tt>$</tt> may appear.
|
|
A full list of variables can be found in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
|
This is a list of the most common variables:
|
|
</p>
|
|
|
|
<p>
|
|
<tt>$1</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
A C local variable corresponding to the actual type specified in the
|
|
<tt>%typemap</tt> directive. For input values, this is a C local variable
|
|
that's supposed to hold an argument value. For output values, this is
|
|
the raw result that's supposed to be returned to Perl.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$input</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
A Perl object holding the value of an argument of variable value.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$result</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
A Perl object that holds the result to be returned to Perl.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$1_name</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
The parameter name that was matched.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$1_type</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
The actual C datatype matched by the typemap.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$1_ltype</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of
|
|
a C assignment operation). This type is stripped of qualifiers and may be an altered version of <tt>$1_type</tt>.
|
|
All arguments and local variables in wrapper functions are declared using this type so that their values can be
|
|
properly assigned.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>$symname</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
The Perl name of the wrapper function being created.
|
|
</div>
|
|
|
|
<H3><a name="Perl5_nn31"></a>31.7.4 Useful functions</H3>
|
|
|
|
|
|
<p>
|
|
When writing typemaps, it is necessary to work directly with Perl5
|
|
objects. This, unfortunately, can be a daunting task. Consult the
|
|
"perlguts" man-page for all of the really ugly details. A short
|
|
summary of commonly used functions is provided here for reference. It
|
|
should be stressed that SWIG can be used quite effectively without
|
|
knowing any of these details--especially now that there are typemap
|
|
libraries that can already been written.
|
|
</p>
|
|
|
|
<p>
|
|
<b>Perl Integer Functions</b>
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int SvIV(SV *);
|
|
void sv_setiv(SV *sv, IV value);
|
|
SV *newSViv(IV value);
|
|
int SvIOK(SV *);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Perl Floating Point Functions</b>
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
double SvNV(SV *);
|
|
void sv_setnv(SV *, double value);
|
|
SV *newSVnv(double value);
|
|
int SvNOK(SV *);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Perl String Functions</b>
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
char *SvPV(SV *, STRLEN len);
|
|
void sv_setpv(SV *, char *val);
|
|
void sv_setpvn(SV *, char *val, STRLEN len);
|
|
SV *newSVpv(char *value, STRLEN len);
|
|
int SvPOK(SV *);
|
|
void sv_catpv(SV *, char *);
|
|
void sv_catpvn(SV *, char *, STRLEN);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Perl References</b>
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void sv_setref_pv(SV *, char *, void *ptr);
|
|
int sv_isobject(SV *);
|
|
SV *SvRV(SV *);
|
|
int sv_isa(SV *, char *0;
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H2><a name="Perl5_nn32"></a>31.8 Typemap Examples</H2>
|
|
|
|
|
|
<p>
|
|
This section includes a few examples of typemaps. For more examples, you
|
|
might look at the files "<tt>perl5.swg</tt>" and "<tt>typemaps.i</tt>" in
|
|
the SWIG library.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn33"></a>31.8.1 Converting a Perl5 array to a char **</H3>
|
|
|
|
|
|
<p>
|
|
A common problem in many C programs is the processing of command line
|
|
arguments, which are usually passed in an array of NULL terminated
|
|
strings. The following SWIG interface file allows a Perl5 array
|
|
reference to be used as a char ** datatype.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module argv
|
|
|
|
// This tells SWIG to treat char ** as a special case
|
|
%typemap(in) char ** {
|
|
AV *tempav;
|
|
I32 len;
|
|
int i;
|
|
SV **tv;
|
|
if (!SvROK($input))
|
|
croak("Argument $argnum is not a reference.");
|
|
if (SvTYPE(SvRV($input)) != SVt_PVAV)
|
|
croak("Argument $argnum is not an array.");
|
|
tempav = (AV*)SvRV($input);
|
|
len = av_len(tempav);
|
|
$1 = (char **) malloc((len+2)*sizeof(char *));
|
|
for (i = 0; i <= len; i++) {
|
|
tv = av_fetch(tempav, i, 0);
|
|
$1[i] = (char *) SvPV(*tv,PL_na);
|
|
}
|
|
$1[i] = NULL;
|
|
};
|
|
|
|
// This cleans up the char ** array after the function call
|
|
%typemap(freearg) char ** {
|
|
free($1);
|
|
}
|
|
|
|
// Creates a new Perl array and places a NULL-terminated char ** into it
|
|
%typemap(out) char ** {
|
|
AV *myav;
|
|
SV **svs;
|
|
int i = 0,len = 0;
|
|
/* Figure out how many elements we have */
|
|
while ($1[len])
|
|
len++;
|
|
svs = (SV **) malloc(len*sizeof(SV *));
|
|
for (i = 0; i < len ; i++) {
|
|
svs[i] = sv_newmortal();
|
|
sv_setpv((SV*)svs[i],$1[i]);
|
|
};
|
|
myav = av_make(len,svs);
|
|
free(svs);
|
|
$result = newRV_noinc((SV*)myav);
|
|
sv_2mortal($result);
|
|
argvi++;
|
|
}
|
|
|
|
// Now a few test functions
|
|
%inline %{
|
|
int print_args(char **argv) {
|
|
int i = 0;
|
|
while (argv[i]) {
|
|
printf("argv[%d] = %s\n", i,argv[i]);
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
// Returns a char ** list
|
|
char **get_args() {
|
|
static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
|
|
return &values[0];
|
|
}
|
|
%}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
When this module is compiled, the wrapped C functions can be used in a
|
|
Perl script as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
use argv;
|
|
@a = ("Dave", "Mike", "John", "Mary"); # Create an array of strings
|
|
argv::print_args(\@a); # Pass it to our C function
|
|
$b = argv::get_args(); # Get array of strings from C
|
|
print @$b,"\n"; # Print it out
|
|
</pre></div>
|
|
|
|
|
|
<H3><a name="Perl5_nn34"></a>31.8.2 Return values</H3>
|
|
|
|
|
|
<p>
|
|
Return values are placed on the argument stack of each wrapper
|
|
function. The current value of the argument stack pointer is
|
|
contained in a variable <tt>argvi</tt>. Whenever a new output value
|
|
is added, it is critical that this value be incremented. For multiple
|
|
output values, the final value of <tt>argvi</tt> should be the total
|
|
number of output values.
|
|
</p>
|
|
|
|
<p>
|
|
The total number of return values should not exceed the number of
|
|
input values unless you explicitly extend the argument stack. This
|
|
can be done using the <tt>EXTEND()</tt> macro as in:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%typemap(argout) int *OUTPUT {
|
|
if (argvi >= items) {
|
|
EXTEND(sp,1); /* Extend the stack by 1 object */
|
|
}
|
|
$result = sv_newmortal();
|
|
sv_setiv($target,(IV) *($1));
|
|
argvi++;
|
|
}
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn35"></a>31.8.3 Returning values from arguments</H3>
|
|
|
|
|
|
<p>
|
|
Sometimes it is desirable for a function to return a value in one of
|
|
its arguments. This example describes the implementation of the <tt>OUTPUT</tt> typemap.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module return
|
|
|
|
// This tells SWIG to treat an double * argument with name 'OutDouble' as
|
|
// an output value.
|
|
|
|
%typemap(argout) double *OUTPUT {
|
|
$result = sv_newmortal();
|
|
sv_setnv($result, *$input);
|
|
argvi++; /* Increment return count -- important! */
|
|
}
|
|
|
|
// We don't care what the input value is. Ignore, but set to a temporary variable
|
|
|
|
%typemap(in,numinputs=0) double *OUTPUT(double junk) {
|
|
$1 = &junk;
|
|
}
|
|
|
|
// Now a function to test it
|
|
%{
|
|
/* Returns the first two input arguments */
|
|
int multout(double a, double b, double *out1, double *out2) {
|
|
*out1 = a;
|
|
*out2 = b;
|
|
return 0;
|
|
};
|
|
%}
|
|
|
|
// If we name both parameters OutDouble both will be output
|
|
|
|
int multout(double a, double b, double *OUTPUT, double *OUTPUT);
|
|
...
|
|
</pre></div>
|
|
|
|
<p>
|
|
When this function is called, the output arguments are appended to the stack used
|
|
to return results. This shows up an array in Perl.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
@r = multout(7,13);
|
|
print "multout(7,13) = @r\n";
|
|
($x,$y) = multout(7,13);
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn36"></a>31.8.4 Accessing array structure members</H3>
|
|
|
|
|
|
<p>
|
|
Consider the following data structure:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
#define SIZE 8
|
|
typedef struct {
|
|
int values[SIZE];
|
|
...
|
|
} Foo;
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
By default, SWIG doesn't know how to the handle the values structure
|
|
member it's an array, not a pointer. In this case, SWIG makes the array member
|
|
read-only. Reading will simply return a pointer to the first item in the array.
|
|
To make the member writable, a "memberin" typemap can be used.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%typemap(memberin) int [SIZE] {
|
|
int i;
|
|
for (i = 0; i < SIZE; i++) {
|
|
$1[i] = $input[i];
|
|
}
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
Whenever a <tt>int [SIZE]</tt> member is encountered in a structure
|
|
or class, this typemap provides a safe mechanism for setting its
|
|
value.
|
|
</p>
|
|
|
|
<p>
|
|
As in the previous example, the typemap can be generalized for any dimension.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%typemap(memberin) int [ANY] {
|
|
int i;
|
|
for (i = 0; i < $1_dim0; i++) {
|
|
$1[i] = $input[i];
|
|
}
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
When setting structure members, the input object is always assumed to
|
|
be a C array of values that have already been converted from the
|
|
target language. Because of this, the <tt>memberin</tt> typemap is
|
|
almost always combined with the use of an "in" typemap. For example,
|
|
the "in" typemap in the previous section would be used to convert an
|
|
<tt>int[]</tt> array to C whereas the "memberin" typemap would be used
|
|
to copy the converted array into a C data structure.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn37"></a>31.8.5 Turning Perl references into C pointers</H3>
|
|
|
|
|
|
<p>
|
|
A frequent confusion on the SWIG mailing list is errors caused by the
|
|
mixing of Perl references and C pointers. For example, suppose you
|
|
have a C function that modifies its arguments like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
void add(double a, double b, double *c) {
|
|
*c = a + b;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
A common misinterpretation of this function is the following Perl script:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Perl script
|
|
$a = 3.5;
|
|
$b = 7.5;
|
|
$c = 0.0; # Output value
|
|
add($a,$b,\$c); # Place result in c (Except that it doesn't work)
|
|
</pre></div>
|
|
|
|
<p>
|
|
To make this work with a reference, you can use a typemap such as this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%typemap(in) double * (double dvalue) {
|
|
SV* tempsv;
|
|
if (!SvROK($input)) {
|
|
croak("expected a reference\n");
|
|
}
|
|
tempsv = SvRV($input);
|
|
if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
|
|
croak("expected a double reference\n");
|
|
}
|
|
dvalue = SvNV(tempsv);
|
|
$1 = &dvalue;
|
|
}
|
|
|
|
%typemap(argout) double * {
|
|
SV *tempsv;
|
|
tempsv = SvRV($input);
|
|
sv_setnv(tempsv, *$1);
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
Now, if you place this before the add function, you can do this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
$a = 3.5;
|
|
$b = 7.5;
|
|
$c = 0.0;
|
|
add($a,$b,\$c); # Now it works!
|
|
print "$c\n";
|
|
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn38"></a>31.8.6 Pointer handling</H3>
|
|
|
|
|
|
<p>
|
|
Occasionally, it might be necessary to convert pointer values that have
|
|
been stored using the SWIG typed-pointer representation. To convert a pointer from Perl to C, the following
|
|
function is used:
|
|
</p>
|
|
|
|
<p>
|
|
<tt>
|
|
int SWIG_ConvertPtr(SV *obj, void **ptr, swig_type_info *ty, int flags)
|
|
</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts a Perl object <tt>obj</tt> to a C pointer. The result of the conversion is placed
|
|
into the pointer located at <tt>ptr</tt>. <tt>ty</tt> is a SWIG type descriptor structure.
|
|
<tt>flags</tt> is used to handle error checking and other aspects of conversion. <tt>flags</tt> is
|
|
currently undefined and reserved for future expansion. Returns 0 on success and -1 on error.
|
|
</div>
|
|
|
|
<p>
|
|
<tt>
|
|
void *SWIG_MakePtr(SV *obj, void *ptr, swig_type_info *ty, int flags)</tt>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Creates a new Perl pointer object. <tt>obj</tt> is a Perl SV that has been initialized to hold the result,
|
|
<tt>ptr</tt> is the pointer to convert, <tt>ty</tt> is the SWIG type descriptor structure that
|
|
describes the type, and <tt>flags</tt> is a flag that controls properties of the conversion. <tt>flags</tt> is currently undefined
|
|
and reserved.
|
|
</div>
|
|
|
|
<p>
|
|
Both of these functions require the use of a special SWIG
|
|
type-descriptor structure. This structure contains information about
|
|
the mangled name of the datatype, type-equivalence information, as
|
|
well as information about converting pointer values under C++
|
|
inheritance. For a type of <tt>Foo *</tt>, the type descriptor structure
|
|
is usually accessed as follows:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
Foo *f;
|
|
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
|
|
|
SV *sv = sv_newmortal();
|
|
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In a typemap, the type descriptor should always be accessed using the special typemap
|
|
variable <tt>$1_descriptor</tt>. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) Foo * {
|
|
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
If necessary, the descriptor for any type can be obtained using the <tt>$descriptor()</tt> macro in a typemap.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%typemap(in) Foo * {
|
|
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<H2><a name="Perl5_nn39"></a>31.9 Proxy classes</H2>
|
|
|
|
|
|
<p>
|
|
<b>Out of date. Needs update.</b>
|
|
</p>
|
|
|
|
<p>
|
|
Using the low-level procedural interface, SWIG can also construct a
|
|
high-level object oriented interface to C structures and C++ classes.
|
|
This is done by constructing a Perl proxy class (also known as a shadow class)
|
|
that provides an OO wrapper
|
|
to the underlying code. This section describes the implementation
|
|
details of the proxy interface.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn40"></a>31.9.1 Preliminaries</H3>
|
|
|
|
|
|
<p>
|
|
Proxy classes, are generated by default. If you want to turn them off, use the <tt>-noproxy</tt> command line option.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
$ swig -c++ -perl -noproxy example.i
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When proxy classes are used, SWIG moves all of the low-level procedural wrappers to
|
|
another package name. By default, this package is named 'modulec' where 'module' is the name of the module
|
|
you provided with the <tt>%module</tt> directive. Then, in place of the original module,
|
|
SWIG creates a collection of high-level Perl wrappers. In your scripts, you will use these
|
|
high level wrappers. The wrappers, in turn, interact with the low-level procedural module.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn41"></a>31.9.2 Structure and class wrappers</H3>
|
|
|
|
|
|
<p>
|
|
Suppose you have the following SWIG interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
struct Vector {
|
|
Vector(double x, double y, double z);
|
|
~Vector();
|
|
double x,y,z;
|
|
};
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
When wrapped, SWIG creates the following set of low-level accessor
|
|
functions as described in previous sections.
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *new_Vector(double x, double y, double z);
|
|
void delete_Vector(Vector *v);
|
|
double Vector_x_get(Vector *v);
|
|
double Vector_x_set(Vector *v, double value);
|
|
double Vector_y_get(Vector *v);
|
|
double Vector_y_set(Vector *v, double value);
|
|
double Vector_z_get(Vector *v);
|
|
double Vector_z_set(Vector *v, double value);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
However, when proxy classes are enabled, these accessor functions are
|
|
wrapped inside a Perl class like this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
package example::Vector;
|
|
@ISA = qw( example );
|
|
%OWNER = ();
|
|
%BLESSEDMEMBERS = ();
|
|
|
|
sub new () {
|
|
my $self = shift;
|
|
my @args = @_;
|
|
$self = vectorc::new_Vector(@args);
|
|
return undef if (!defined($self));
|
|
bless $self, "example::Vector";
|
|
$OWNER{$self} = 1;
|
|
my %retval;
|
|
tie %retval, "example::Vector", $self;
|
|
return bless \%retval,"Vector";
|
|
}
|
|
|
|
sub DESTROY {
|
|
return unless $_[0]->isa('HASH');
|
|
my $self = tied(%{$_[0]});
|
|
delete $ITERATORS{$self};
|
|
if (exists $OWNER{$self}) {
|
|
examplec::delete_Vector($self));
|
|
delete $OWNER{$self};
|
|
}
|
|
|
|
sub FETCH {
|
|
my ($self,$field) = @_;
|
|
my $member_func = "vectorc::Vector_${field}_get";
|
|
my $val = &$member_func($self);
|
|
if (exists $BLESSEDMEMBERS{$field}) {
|
|
return undef if (!defined($val));
|
|
my %retval;
|
|
tie %retval,$BLESSEDMEMBERS{$field},$val;
|
|
return bless \%retval, $BLESSEDMEMBERS{$field};
|
|
}
|
|
return $val;
|
|
}
|
|
|
|
sub STORE {
|
|
my ($self,$field,$newval) = @_;
|
|
my $member_func = "vectorc::Vector_${field}_set";
|
|
if (exists $BLESSEDMEMBERS{$field}) {
|
|
&$member_func($self,tied(%{$newval}));
|
|
} else {
|
|
&$member_func($self,$newval);
|
|
}
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
Each structure or class is mapped into a Perl package of the same
|
|
name. The C++ constructors and destructors are mapped into
|
|
constructors and destructors for the package and are always named
|
|
"new" and "DESTROY". The constructor always returns a tied hash
|
|
table. This hash table is used to access the member variables of a
|
|
structure in addition to being able to invoke member functions. The
|
|
<tt>%OWNER</tt> and <tt>%BLESSEDMEMBERS</tt> hash tables are used
|
|
internally and described shortly.
|
|
</p>
|
|
|
|
<p>
|
|
To use our new proxy class we can simply do the following:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Perl code using Vector class
|
|
$v = new Vector(2,3,4);
|
|
$w = Vector->new(-1,-2,-3);
|
|
|
|
# Assignment of a single member
|
|
$v->{x} = 7.5;
|
|
|
|
# Assignment of all members
|
|
%$v = ( x=>3,
|
|
y=>9,
|
|
z=>-2);
|
|
|
|
# Reading members
|
|
$x = $v->{x};
|
|
|
|
# Destruction
|
|
$v->DESTROY();
|
|
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn42"></a>31.9.3 Object Ownership</H3>
|
|
|
|
|
|
<p>
|
|
In order for proxy classes to work properly, it is necessary for Perl
|
|
to manage some mechanism of object ownership. Here's the crux of the
|
|
problem---suppose you had a function like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *Vector_get(Vector *v, int index) {
|
|
return &v[i];
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
This function takes a Vector pointer and returns a pointer to another
|
|
Vector. Such a function might be used to manage arrays or lists of
|
|
vectors (in C). Now contrast this function with the constructor for a
|
|
Vector object:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
Vector *new_Vector(double x, double y, double z) {
|
|
Vector *v;
|
|
v = new Vector(x,y,z); // Call C++ constructor
|
|
return v;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
Both functions return a Vector, but the constructor is returning a
|
|
brand-new Vector while the other function is returning a Vector that
|
|
was already created (hopefully). In Perl, both vectors will be
|
|
indistinguishable---clearly a problem considering that we would
|
|
probably like the newly created Vector to be destroyed when we are
|
|
done with it.
|
|
</p>
|
|
|
|
<p>
|
|
To manage these problems, each class contains two methods that access
|
|
an internal hash table called <tt>%OWNER</tt>. This hash keeps a list
|
|
of all of the objects that Perl knows that it has created. This
|
|
happens in two cases: (1) when the constructor has been called, and
|
|
(2) when a function implicitly creates a new object (as is done when
|
|
SWIG needs to return a complex datatype by value). When the
|
|
destructor is invoked, the Perl proxy class module checks the
|
|
<tt>%OWNER</tt> hash to see if Perl created the object. If so, the
|
|
C/C++ destructor is invoked. If not, we simply destroy the Perl
|
|
object and leave the underlying C object alone (under the assumption
|
|
that someone else must have created it).
|
|
</p>
|
|
|
|
<p>
|
|
This scheme works remarkably well in practice but it isn't foolproof.
|
|
In fact, it will fail if you create a new C object in Perl, pass it on
|
|
to a C function that remembers the object, and then destroy the
|
|
corresponding Perl object (this situation turns out to come up
|
|
frequently when constructing objects like linked lists and trees).
|
|
When C takes possession of an object, you can change Perl's ownership
|
|
by simply deleting the object from the <tt>%OWNER</tt> hash. This is
|
|
done using the <tt>DISOWN</tt> method.
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Perl code to change ownership of an object
|
|
$v = new Vector(x,y,z);
|
|
$v->DISOWN();
|
|
</pre></div>
|
|
|
|
<p>
|
|
To acquire ownership of an object, the <tt>ACQUIRE</tt> method can be used.
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Given Perl ownership of a file
|
|
$u = Vector_get($v);
|
|
$u->ACQUIRE();
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
As always, a little care is in order. SWIG does not provide reference
|
|
counting, garbage collection, or advanced features one might find in
|
|
sophisticated languages.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn43"></a>31.9.4 Nested Objects</H3>
|
|
|
|
|
|
<p>
|
|
Suppose that we have a new object that looks like this:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
struct Particle {
|
|
Vector r;
|
|
Vector v;
|
|
Vector f;
|
|
int type;
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
In this case, the members of the structure are complex objects that
|
|
have already been encapsulated in a Perl proxy class. To handle
|
|
these correctly, we use the <tt>%BLESSEDMEMBERS</tt> hash which would
|
|
look like this (along with some supporting code):
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
package Particle;
|
|
...
|
|
%BLESSEDMEMBERS = (
|
|
r => `Vector',
|
|
v => `Vector',
|
|
f => `Vector',
|
|
);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
When fetching members from the structure, <tt>%BLESSEDMEMBERS</tt> is
|
|
checked. If the requested field is present, we create a tied-hash
|
|
table and return it. If not, we just return the corresponding member
|
|
unmodified.
|
|
</p>
|
|
|
|
<p>
|
|
This implementation allows us to operate on nested structures as follows:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
# Perl access of nested structure
|
|
$p = new Particle();
|
|
$p->{f}->{x} = 0.0;
|
|
%${$p->{v}} = ( x=>0, y=>0, z=>0);
|
|
</pre></div>
|
|
|
|
<H3><a name="Perl5_nn44"></a>31.9.5 Proxy Functions</H3>
|
|
|
|
|
|
<p>
|
|
When functions take arguments involving a complex object, it is
|
|
sometimes necessary to write a proxy function. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
double dot_product(Vector *v1, Vector *v2);
|
|
</pre></div>
|
|
|
|
<p>
|
|
Since Vector is an object already wrapped into a proxy class, we need
|
|
to modify this function to accept arguments that are given in the form
|
|
of tied hash tables. This is done by creating a Perl function like
|
|
this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
sub dot_product {
|
|
my @args = @_;
|
|
$args[0] = tied(%{$args[0]}); # Get the real pointer values
|
|
$args[1] = tied(%{$args[1]});
|
|
my $result = vectorc::dot_product(@args);
|
|
return $result;
|
|
}
|
|
</pre></div>
|
|
|
|
<p>
|
|
This function replaces the original function, but operates in an
|
|
identical manner.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn45"></a>31.9.6 Inheritance</H3>
|
|
|
|
|
|
<p>
|
|
Simple C++ inheritance is handled using the Perl <tt>@ISA</tt> array
|
|
in each class package. For example, if you have the following
|
|
interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
// shapes.i
|
|
// SWIG interface file for shapes class
|
|
%module shapes
|
|
%{
|
|
#include "shapes.h"
|
|
%}
|
|
|
|
class Shape {
|
|
public:
|
|
virtual double area() = 0;
|
|
virtual double perimeter() = 0;
|
|
void set_location(double x, double y);
|
|
};
|
|
class Circle : public Shape {
|
|
public:
|
|
Circle(double radius);
|
|
~Circle();
|
|
double area();
|
|
double perimeter();
|
|
};
|
|
class Square : public Shape {
|
|
public:
|
|
Square(double size);
|
|
~Square();
|
|
double area();
|
|
double perimeter();
|
|
}
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
The resulting, Perl wrapper class will create the following code:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
Package Shape;
|
|
@ISA = (shapes);
|
|
...
|
|
Package Circle;
|
|
@ISA = (shapes Shape);
|
|
...
|
|
Package Square;
|
|
@ISA = (shapes Shape);
|
|
|
|
</pre></div>
|
|
|
|
<p>
|
|
The <tt>@ISA</tt> array determines where to look for methods of a
|
|
particular class. In this case, both the <tt>Circle</tt> and
|
|
<tt>Square</tt> classes inherit functions from <tt>Shape</tt> so we'll
|
|
want to look in the <tt>Shape</tt> base class for them. All classes
|
|
also inherit from the top-level module <tt>shapes</tt>. This is
|
|
because certain common operations needed to implement proxy classes
|
|
are implemented only once and reused in the wrapper code for various
|
|
classes and structures.
|
|
</p>
|
|
|
|
<p>
|
|
Since SWIG proxy classes are implemented in Perl, it is easy to
|
|
subclass from any SWIG generated class. To do this, simply put the
|
|
name of a SWIG class in the <tt>@ISA</tt> array for your new
|
|
class. However, be forewarned that this is not a trivial problem. In
|
|
particular, inheritance of data members is extremely tricky (and I'm
|
|
not even sure if it really works).
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn46"></a>31.9.7 Modifying the proxy methods</H3>
|
|
|
|
|
|
<p>
|
|
It is possible to override the SWIG generated proxy/shadow methods, using <tt>%feature("shadow")</tt>.
|
|
It works like all the other <a href="Customization.html#Customization_features">%feature directives</a>.
|
|
Here is a simple example showing how to add some Perl debug code to the constructor:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
/* Let's make the constructor of the class Square more verbose */
|
|
%feature("shadow") Square(double w)
|
|
%{
|
|
sub new {
|
|
my $pkg = shift;
|
|
my $self = examplec::new_Square(@_);
|
|
print STDERR "Constructed an @{[ref($self)]}\n";
|
|
bless $self, $pkg if defined($self);
|
|
}
|
|
%}
|
|
|
|
class Square {
|
|
public:
|
|
Square(double w);
|
|
...
|
|
};
|
|
</pre></div>
|
|
|
|
<H2><a name="Perl5_nn47"></a>31.10 Adding additional Perl code</H2>
|
|
|
|
|
|
<p>
|
|
If writing support code in C isn't enough, it is also possible to write code in
|
|
Perl. This code gets inserted in to the <tt>.pm</tt> file created by SWIG. One
|
|
use of Perl code might be to supply a high-level interface to certain functions.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void set_transform(Image *im, double x[4][4]);
|
|
|
|
...
|
|
/* Rewrite the high level interface to set_transform */
|
|
%perlcode %{
|
|
sub set_transform
|
|
{
|
|
my ($im, $x) = @_;
|
|
my $a = new_mat44();
|
|
for (my $i = 0; $i < 4, $i++)
|
|
{
|
|
for (my $j = 0; $j < 4, $j++)
|
|
{
|
|
mat44_set($a, $i, $j, $x->[i][j])
|
|
}
|
|
}
|
|
example.set_transform($im, $a);
|
|
free_mat44($a);
|
|
}
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this example, <tt>set_transform()</tt> provides a high-level Perl interface built on top of
|
|
low-level helper functions. For example, this code now seems to work:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
my $a =
|
|
[[1,0,0,0],
|
|
[0,1,0,0],
|
|
[0,0,1,0],
|
|
[0,0,0,1]];
|
|
set_transform($im, $a);
|
|
</pre>
|
|
</div>
|
|
|
|
<H2><a name="Perl5_directors"></a>31.11 Cross language polymorphism</H2>
|
|
|
|
|
|
<p>
|
|
Proxy classes provide a more natural, object-oriented way to access
|
|
extension classes. As described above, each proxy instance has an
|
|
associated C++ instance, and method calls to the proxy are passed to the
|
|
C++ instance transparently via C wrapper functions.
|
|
</p>
|
|
|
|
<p>
|
|
This arrangement is asymmetric in the sense that no corresponding
|
|
mechanism exists to pass method calls down the inheritance chain from
|
|
C++ to Perl. In particular, if a C++ class has been extended in Perl
|
|
(by extending the proxy class), these extensions will not be visible
|
|
from C++ code. Virtual method calls from C++ are thus not able access
|
|
the lowest implementation in the inheritance chain.
|
|
</p>
|
|
|
|
<p>
|
|
Changes have been made to SWIG to address this problem and
|
|
make the relationship between C++ classes and proxy classes more
|
|
symmetric. To achieve this goal, new classes called directors are
|
|
introduced at the bottom of the C++ inheritance chain. The job of the
|
|
directors is to route method calls correctly, either to C++
|
|
implementations higher in the inheritance chain or to Perl
|
|
implementations lower in the inheritance chain. The upshot is that C++
|
|
classes can be extended in Perl and from C++ these extensions look
|
|
exactly like native C++ classes. Neither C++ code nor Perl code needs
|
|
to know where a particular method is implemented: the combination of
|
|
proxy classes, director classes, and C wrapper functions takes care of
|
|
all the cross-language method routing transparently.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn48"></a>31.11.1 Enabling directors</H3>
|
|
|
|
|
|
<p>
|
|
The director feature is disabled by default. To use directors you
|
|
must make two changes to the interface file. First, add the "directors"
|
|
option to the %module directive, like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%module(directors="1") modulename
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Without this option no director code will be generated. Second, you
|
|
must use the %feature("director") directive to tell SWIG which classes
|
|
and methods should get directors. The %feature directive can be applied
|
|
globally, to specific classes, and to specific methods, like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
// generate directors for all classes that have virtual methods
|
|
%feature("director");
|
|
|
|
// generate directors for all virtual methods in class Foo
|
|
%feature("director") Foo;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
You can use the %feature("nodirector") directive to turn off
|
|
directors for specific classes or methods. So for example,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director") Foo;
|
|
%feature("nodirector") Foo::bar;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
will generate directors for all virtual methods of class Foo except
|
|
bar().
|
|
</p>
|
|
|
|
<p>
|
|
Directors can also be generated implicitly through inheritance.
|
|
In the following, class Bar will get a director class that handles
|
|
the methods one() and two() (but not three()):
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director") Foo;
|
|
class Foo {
|
|
public:
|
|
Foo(int foo);
|
|
virtual void one();
|
|
virtual void two();
|
|
};
|
|
|
|
class Bar: public Foo {
|
|
public:
|
|
virtual void three();
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
then at the Perl side you can define
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
use mymodule;
|
|
|
|
package MyFoo;
|
|
use base 'mymodule::Foo';
|
|
|
|
sub one {
|
|
print "one from Perl\n";
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H3><a name="Perl5_nn49"></a>31.11.2 Director classes</H3>
|
|
|
|
|
|
|
|
|
|
|
|
<p>
|
|
For each class that has directors enabled, SWIG generates a new class
|
|
that derives from both the class in question and a special
|
|
<tt>Swig::Director</tt> class. These new classes, referred to as director
|
|
classes, can be loosely thought of as the C++ equivalent of the Perl
|
|
proxy classes. The director classes store a pointer to their underlying
|
|
Perl object and handle various issues related to object ownership.
|
|
</p>
|
|
|
|
<p>
|
|
For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
|
|
original C++ class as the director's base class. By default, a director
|
|
class extends all virtual methods in the inheritance chain of its base
|
|
class (see the preceding section for how to modify this behavior).
|
|
Thus all virtual method calls, whether they originate in C++ or in
|
|
Perl via proxy classes, eventually end up in at the implementation in
|
|
the director class. The job of the director methods is to route these
|
|
method calls to the appropriate place in the inheritance chain. By
|
|
"appropriate place" we mean the method that would have been called if
|
|
the C++ base class and its extensions in Perl were seamlessly
|
|
integrated. That seamless integration is exactly what the director
|
|
classes provide, transparently skipping over all the messy extension API
|
|
glue that binds the two languages together.
|
|
</p>
|
|
|
|
<p>
|
|
In reality, the "appropriate place" is one of only two possibilities:
|
|
C++ or Perl. Once this decision is made, the rest is fairly easy. If
|
|
the correct implementation is in C++, then the lowest implementation of
|
|
the method in the C++ inheritance chain is called explicitly. If the
|
|
correct implementation is in Perl, the Perl API is used to call the
|
|
method of the underlying Perl object (after which the usual virtual
|
|
method resolution in Perl automatically finds the right
|
|
implementation).
|
|
</p>
|
|
|
|
<p>
|
|
Now how does the director decide which language should handle the method call?
|
|
The basic rule is to handle the method in Perl, unless there's a good
|
|
reason not to. The reason for this is simple: Perl has the most
|
|
"extended" implementation of the method. This assertion is guaranteed,
|
|
since at a minimum the Perl proxy class implements the method. If the
|
|
method in question has been extended by a class derived from the proxy
|
|
class, that extended implementation will execute exactly as it should.
|
|
If not, the proxy class will route the method call into a C wrapper
|
|
function, expecting that the method will be resolved in C++. The wrapper
|
|
will call the virtual method of the C++ instance, and since the director
|
|
extends this the call will end up right back in the director method. Now
|
|
comes the "good reason not to" part. If the director method were to blindly
|
|
call the Perl method again, it would get stuck in an infinite loop. We avoid this
|
|
situation by adding special code to the C wrapper function that tells
|
|
the director method to not do this. The C wrapper function compares the
|
|
pointer to the Perl object that called the wrapper function to the
|
|
pointer stored by the director. If these are the same, then the C
|
|
wrapper function tells the director to resolve the method by calling up
|
|
the C++ inheritance chain, preventing an infinite loop.
|
|
</p>
|
|
|
|
<p>
|
|
One more point needs to be made about the relationship between director
|
|
classes and proxy classes. When a proxy class instance is created in
|
|
Perl, SWIG creates an instance of the original C++ class.
|
|
This is exactly what happens without directors and
|
|
is true even if directors are enabled for the particular class in
|
|
question. When a class <i>derived</i> from a proxy class is created,
|
|
however, SWIG then creates an instance of the corresponding C++ director
|
|
class. The reason for this difference is that user-defined subclasses
|
|
may override or extend methods of the original class, so the director
|
|
class is needed to route calls to these methods correctly. For
|
|
unmodified proxy classes, all methods are ultimately implemented in C++
|
|
so there is no need for the extra overhead involved with routing the
|
|
calls through Perl.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn50"></a>31.11.3 Ownership and object destruction</H3>
|
|
|
|
|
|
<p>
|
|
Memory management issues are slightly more complicated with directors
|
|
than for proxy classes alone. Perl instances hold a pointer to the
|
|
associated C++ director object, and the director in turn holds a pointer
|
|
back to a Perl object. By default, proxy classes own their C++
|
|
director object and take care of deleting it when they are garbage
|
|
collected.
|
|
</p>
|
|
|
|
<p>
|
|
This relationship can be reversed by calling the special
|
|
<tt>DISOWN()</tt> method of the proxy class. After calling this
|
|
method the director
|
|
class increments the reference count of the Perl object. When the
|
|
director class is deleted it decrements the reference count. Assuming no
|
|
outstanding references to the Perl object remain, the Perl object
|
|
will be destroyed at the same time. This is a good thing, since
|
|
directors and proxies refer to each other and so must be created and
|
|
destroyed together. Destroying one without destroying the other will
|
|
likely cause your program to segfault.
|
|
</p>
|
|
|
|
<p>
|
|
Also note that due to the proxy implementation, the <tt>DESTROY()</tt>
|
|
method on directors can be called for several reasons, many of which
|
|
have little to do with the teardown of an object instance. To help
|
|
disambiguate this, a second argument is added to the <tt>DESTROY()</tt>
|
|
call when a C++ director object is being released. So, to avoid running
|
|
your clean-up code when an object is not really going away, or after it
|
|
has already been reclaimed, it is suggested that custom destructors in
|
|
Perl subclasses looks something like:
|
|
</p>
|
|
|
|
<div class="targetlang">
|
|
<pre>
|
|
sub DESTROY {
|
|
my($self, $final) = @_;
|
|
if($final) {
|
|
# real teardown code
|
|
}
|
|
shift->SUPER::DESTROY(@_);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H3><a name="Perl5_nn51"></a>31.11.4 Exception unrolling</H3>
|
|
|
|
|
|
<p>
|
|
With directors routing method calls to Perl, and proxies routing them
|
|
to C++, the handling of exceptions is an important concern. By default, the
|
|
directors ignore exceptions that occur during method calls that are
|
|
resolved in Perl. To handle such exceptions correctly, it is necessary
|
|
to temporarily translate them into C++ exceptions. This can be done with
|
|
the %feature("director:except") directive. The following code should
|
|
suffice in most cases:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("director:except") {
|
|
if ($error != NULL) {
|
|
throw Swig::DirectorMethodException();
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This code will check the Perl error state after each method call from
|
|
a director into Perl, and throw a C++ exception if an error occurred.
|
|
This exception can be caught in C++ to implement an error handler.
|
|
</p>
|
|
|
|
<p>
|
|
It may be the case that a method call originates in Perl, travels up
|
|
to C++ through a proxy class, and then back into Perl via a director
|
|
method. If an exception occurs in Perl at this point, it would be nice
|
|
for that exception to find its way back to the original caller. This can
|
|
be done by combining a normal %exception directive with the
|
|
<tt>director:except</tt> handler shown above. Here is an example of a
|
|
suitable exception handler:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%exception {
|
|
try { $action }
|
|
catch (Swig::DirectorException &e) { SWIG_fail; }
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The class Swig::DirectorException used in this example is actually a
|
|
base class of Swig::DirectorMethodException, so it will trap this
|
|
exception. Because the Perl error state is still set when
|
|
Swig::DirectorMethodException is thrown, Perl will register the
|
|
exception as soon as the C wrapper function returns.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn52"></a>31.11.5 Overhead and code bloat</H3>
|
|
|
|
|
|
<p>
|
|
Enabling directors for a class will generate a new director method for
|
|
every virtual method in the class' inheritance chain. This alone can
|
|
generate a lot of code bloat for large hierarchies. Method arguments
|
|
that require complex conversions to and from target language types can
|
|
result in large director methods. For this reason it is recommended that
|
|
you selectively enable directors only for specific classes that are
|
|
likely to be extended in Perl and used in C++.
|
|
</p>
|
|
|
|
<p>
|
|
Compared to classes that do not use directors, the call routing in the
|
|
director methods does add some overhead. In particular, at least one
|
|
dynamic cast and one extra function call occurs per method call from
|
|
Perl. Relative to the speed of Perl execution this is probably
|
|
completely negligible. For worst case routing, a method call that
|
|
ultimately resolves in C++ may take one extra detour through Perl in
|
|
order to ensure that the method does not have an extended Perl
|
|
implementation. This could result in a noticeable overhead in some cases.
|
|
</p>
|
|
|
|
<p>
|
|
Although directors make it natural to mix native C++ objects with Perl
|
|
objects (as director objects) via a common base class pointer, one
|
|
should be aware of the obvious fact that method calls to Perl objects
|
|
will be much slower than calls to C++ objects. This situation can be
|
|
optimized by selectively enabling director methods (using the %feature
|
|
directive) for only those methods that are likely to be extended in
|
|
Perl.
|
|
</p>
|
|
|
|
<H3><a name="Perl5_nn53"></a>31.11.6 Typemaps</H3>
|
|
|
|
|
|
<p>
|
|
Typemaps for input and output of most of the basic types from director
|
|
classes have been written. These are roughly the reverse of the usual
|
|
input and output typemaps used by the wrapper code. The typemap
|
|
operation names are 'directorin', 'directorout', and 'directorargout'.
|
|
The director code does not currently use any of the other kinds of typemaps.
|
|
It is not clear at this point which kinds are appropriate and
|
|
need to be supported.
|
|
</p>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|