| <!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>27 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>27.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>27.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>27.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>27.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 commands 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>27.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>27.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/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>27.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>27.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 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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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>27.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#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>27.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> |
| |
| |
| |
| </body> |
| </html> |