/tags/rel-1-3-29/SWIG/Doc/Manual/Perl5.html
# · HTML · 2560 lines · 2061 code · 476 blank · 23 comment · 0 complexity · 8157f1d2db4a2d0e7436f2bf1f033f68 MD5 · raw file
- <!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>26 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>
- </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 Perl5.003 or
- later. Earlier versions are problematic and SWIG generated extensions
- may not compile or run correctly.
- </p>
- <H2><a name="Perl5_nn2"></a>26.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>26.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>26.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/perl5/5.00503/i386-linux/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
- loaded, an easy way to find out is to run Perl itself.
- </p>
- <div class="code">
- <pre>
- % perl -e 'use Config; print $Config{archlib};'
- /usr/lib/perl5/5.00503/i386-linux
- </pre>
- </div>
- <H3><a name="Perl5_nn5"></a>26.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. To do this, you will need to compile your program
- using comands like this (shown for Linux):
- </p>
- <div class="code"><pre>
- $ swig -perl example.i
- % gcc example.c
- % gcc -c example_wrap.c -I/usr/lib/perl5/5.00503/i386-linux/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>26.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>26.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>permain.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/perl5/5.00503/i386-linux/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>26.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: /usr/lib/perl5/5.00503/i386-lin
- ux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/pe
- rl5/site_perl/5.005 .) 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/perl5/5.00503/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/perl5/5.00503/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>26.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++ -c example.cxx
- % g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/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
- % g++ -c example.cxx
- % g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE
- % g++ -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++ -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};'
- </pre></div>
- <p>
- So you could also compile the wrapper like
- </p>
- <div class="code"><pre>
- % g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \
- `perl -e 'use Config; 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 alot 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>26.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>26.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>26.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>26.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>26.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>26.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>26.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">Creatng 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>26.4.3 Constants</H3>
- <p>
- 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>
- <H3><a name="Perl5_nn18"></a>26.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>26.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>26.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>26.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 necesssary, 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>26.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>26.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>26.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 alot 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>
- 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>26.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>26.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>26.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>26.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 ommitted):
- </p>
- <div class="targetlang">
- <pre>
- example::count("e","Hello World");
- 1
- >>>
- </pre>
- </div>
- <H3><a name="Perl5_nn29"></a>26.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>26.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>26.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 usef 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>26.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>26.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((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>26.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>26.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>26.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>26.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>26.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>26.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>26.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>26.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