| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <title>Typemaps</title> |
| <link rel="stylesheet" type="text/css" href="style.css"> |
| </head> |
| |
| <body bgcolor="#ffffff"> |
| <H1><a name="Typemaps"></a>10 Typemaps</H1> |
| <!-- INDEX --> |
| <div class="sectiontoc"> |
| <ul> |
| <li><a href="#Typemaps_nn2">Introduction</a> |
| <ul> |
| <li><a href="#Typemaps_nn3">Type conversion</a> |
| <li><a href="#Typemaps_nn4">Typemaps</a> |
| <li><a href="#Typemaps_nn5">Pattern matching</a> |
| <li><a href="#Typemaps_nn6">Reusing typemaps</a> |
| <li><a href="#Typemaps_nn7">What can be done with typemaps?</a> |
| <li><a href="#Typemaps_nn8">What can't be done with typemaps?</a> |
| <li><a href="#Typemaps_nn9">The rest of this chapter</a> |
| </ul> |
| <li><a href="#Typemaps_nn10">Typemap specifications</a> |
| <ul> |
| <li><a href="#Typemaps_nn11">Defining a typemap</a> |
| <li><a href="#Typemaps_nn12">Typemap scope</a> |
| <li><a href="#Typemaps_nn13">Copying a typemap</a> |
| <li><a href="#Typemaps_nn14">Deleting a typemap</a> |
| <li><a href="#Typemaps_nn15">Placement of typemaps</a> |
| </ul> |
| <li><a href="#Typemaps_nn16">Pattern matching rules</a> |
| <ul> |
| <li><a href="#Typemaps_nn17">Basic matching rules</a> |
| <li><a href="#Typemaps_nn18">Typedef reductions</a> |
| <li><a href="#Typemaps_nn19">Default typemaps</a> |
| <li><a href="#Typemaps_mixed_default">Mixed default typemaps</a> |
| <li><a href="#Typemaps_nn20">Multi-arguments typemaps</a> |
| </ul> |
| <li><a href="#Typemaps_nn21">Code generation rules</a> |
| <ul> |
| <li><a href="#Typemaps_nn22">Scope</a> |
| <li><a href="#Typemaps_nn23">Declaring new local variables</a> |
| <li><a href="#Typemaps_special_variables">Special variables</a> |
| </ul> |
| <li><a href="#Typemaps_nn25">Common typemap methods</a> |
| <ul> |
| <li><a href="#Typemaps_nn26">"in" typemap</a> |
| <li><a href="#Typemaps_nn27">"typecheck" typemap</a> |
| <li><a href="#Typemaps_nn28">"out" typemap</a> |
| <li><a href="#Typemaps_nn29">"arginit" typemap</a> |
| <li><a href="#Typemaps_nn30">"default" typemap</a> |
| <li><a href="#Typemaps_nn31">"check" typemap</a> |
| <li><a href="#Typemaps_nn32">"argout" typemap</a> |
| <li><a href="#Typemaps_nn33">"freearg" typemap</a> |
| <li><a href="#Typemaps_nn34">"newfree" typemap</a> |
| <li><a href="#Typemaps_nn35">"memberin" typemap</a> |
| <li><a href="#Typemaps_nn36">"varin" typemap</a> |
| <li><a href="#Typemaps_nn37">"varout" typemap</a> |
| <li><a href="#throws_typemap">"throws" typemap</a> |
| </ul> |
| <li><a href="#Typemaps_nn39">Some typemap examples</a> |
| <ul> |
| <li><a href="#Typemaps_nn40">Typemaps for arrays</a> |
| <li><a href="#Typemaps_nn41">Implementing constraints with typemaps</a> |
| </ul> |
| <li><a href="#Typemaps_nn43">Typemaps for multiple languages</a> |
| <li><a href="#Typemaps_optimal">Optimal code generation when returning by value</a> |
| <li><a href="#Typemaps_nn42">Multi-argument typemaps</a> |
| <li><a href="#runtime_type_checker">The run-time type checker</a> |
| <ul> |
| <li><a href="#Typemaps_nn45">Implementation</a> |
| <li><a href="#Typemaps_nn46">Usage</a> |
| </ul> |
| <li><a href="#Typemaps_overloading">Typemaps and overloading</a> |
| <li><a href="#Typemaps_nn48">More about <tt>%apply</tt> and <tt>%clear</tt></a> |
| <li><a href="#Typemaps_nn49">Reducing wrapper code size</a> |
| <li><a href="#Typemaps_nn47">Passing data between typemaps</a> |
| <li><a href="#Typemaps_nn51">Where to go for more information?</a> |
| </ul> |
| </div> |
| <!-- INDEX --> |
| |
| |
| |
| <p> |
| <b>Disclaimer: This chapter is under construction!</b> |
| </p> |
| |
| <H2><a name="Typemaps_nn2"></a>10.1 Introduction</H2> |
| |
| |
| <p> |
| Chances are, you are reading this chapter for one of two reasons; you |
| either want to customize SWIG's behavior or you overheard someone |
| mumbling some incomprehensible drivel about "typemaps" and you asked |
| yourself "typemaps, what are those?" That said, let's start with a |
| short disclaimer that "typemaps" are an advanced customization feature |
| that provide direct access to SWIG's low-level code generator. Not |
| only that, they are an integral part of the SWIG C++ type system (a |
| non-trivial topic of its own). Typemaps are generally |
| <em>not</em> a required part of using SWIG. Therefore, you might want |
| to re-read the earlier chapters if you have found your way to this |
| chapter with only a vague idea of what SWIG already does by default. |
| </p> |
| |
| <H3><a name="Typemaps_nn3"></a>10.1.1 Type conversion</H3> |
| |
| |
| <p> |
| One of the most important problems in wrapper code generation is the |
| conversion of datatypes between programming languages. Specifically, |
| for every C/C++ declaration, SWIG must somehow generate wrapper code |
| that allows values to be passed back and forth between languages. |
| Since every programming language represents data differently, this is |
| not a simple of matter of simply linking code together with the |
| C linker. Instead, SWIG has to know something about how data is |
| represented in each language and how it can be manipulated. |
| </p> |
| |
| <p> |
| To illustrate, suppose you had a simple C function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int factorial(int n); |
| </pre> |
| </div> |
| |
| <p> |
| To access this function from Python, a pair of Python API functions |
| are used to convert integer values. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| long PyInt_AsLong(PyObject *obj); /* Python --> C */ |
| PyObject *PyInt_FromLong(long x); /* C --> Python */ |
| </pre> |
| </div> |
| |
| <p> |
| The first function is used to convert the input argument from a Python integer object |
| to C <tt>long</tt>. The second function is used to convert a value from C back into a Python integer object. |
| </p> |
| |
| <p> |
| Inside the wrapper function, you might see these functions used like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| PyObject *wrap_factorial(PyObject *self, PyObject *args) { |
| int arg1; |
| int result; |
| PyObject *obj1; |
| PyObject *resultobj; |
| |
| if (!PyArg_ParseTuple("O:factorial", &obj1)) return NULL; |
| <b>arg1 = PyInt_AsLong(obj1);</b> |
| result = factorial(arg1); |
| <b>resultobj = PyInt_FromLong(result);</b> |
| return resultobj; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Every target language supported by SWIG has functions that work in a similar manner. For example, in |
| Perl, the following functions are used: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| IV SvIV(SV *sv); /* Perl --> C */ |
| void sv_setiv(SV *sv, IV val); /* C --> Perl */ |
| </pre> |
| </div> |
| |
| <p> |
| In Tcl: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *obj, long *value); |
| Tcl_Obj *Tcl_NewIntObj(long value); |
| </pre> |
| </div> |
| |
| <p> |
| The precise details are not so important. What is important is that |
| all of the underlying type conversion is handled by collections of |
| utility functions and short bits of C code like this---you simply have |
| to read the extension documentation for your favorite language to know |
| how it works (an exercise left to the reader). |
| </p> |
| |
| <H3><a name="Typemaps_nn4"></a>10.1.2 Typemaps</H3> |
| |
| |
| <p> |
| Since type handling is so central to wrapper code generation, SWIG |
| allows it to be completely defined (or redefined) by the user. To do this, |
| a special <tt>%typemap</tt> directive is used. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Convert from Python --> C */ |
| %typemap(in) int { |
| $1 = PyInt_AsLong($input); |
| } |
| |
| /* Convert from C --> Python */ |
| %typemap(out) int { |
| $result = PyInt_FromLong($1); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| At first glance, this code will look a little confusing. |
| However, there is really not much to it. The first typemap (the "in" |
| typemap) is used to convert a value from the target language to C. The second |
| typemap (the "out" typemap) is used to convert in the other |
| direction. The content of each typemap is a small fragment of C code |
| that is inserted directly into the SWIG generated wrapper functions. Within |
| this code, a number of special variables prefixed with a $ are expanded. These are |
| really just placeholders for C variables that are generated in the course |
| of creating the wrapper function. In this case, <tt>$input</tt> refers to an |
| input object that needs to be converted to C and <tt>$result</tt> |
| refers to an object that is going to be returned by a wrapper |
| function. <tt>$1</tt> refers to a C variable that has the same type as |
| specified in the typemap declaration (an <tt>int</tt> in this |
| example). |
| </p> |
| |
| <p> |
| A short example might make this a little more clear. If you were wrapping a |
| function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int gcd(int x, int y); |
| </pre> |
| </div> |
| |
| <p> |
| A wrapper function would look approximately like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| PyObject *wrap_gcd(PyObject *self, PyObject *args) { |
| int arg1; |
| int arg2; |
| int result; |
| PyObject *obj1; |
| PyObject *obj2; |
| PyObject *resultobj; |
| |
| if (!PyArg_ParseTuple("OO:gcd", &obj1, &obj2)) return NULL; |
| |
| /* "in" typemap, argument 1 */<b> |
| { |
| arg1 = PyInt_AsLong(obj1); |
| } |
| </b> |
| /* "in" typemap, argument 2 */<b> |
| { |
| arg2 = PyInt_AsLong(obj2); |
| } |
| </b> |
| result = gcd(arg1,arg2); |
| |
| /* "out" typemap, return value */<b> |
| { |
| resultobj = PyInt_FromLong(result); |
| } |
| </b> |
| return resultobj; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this code, you can see how the typemap code has been inserted into |
| the function. You can also see how the special $ variables have been |
| expanded to match certain variable names inside the wrapper function. This is really the |
| whole idea behind typemaps--they simply let you insert arbitrary code into different |
| parts of the generated wrapper functions. Because arbitrary code can be inserted, it |
| possible to completely change the way in which values are converted. |
| </p> |
| |
| <H3><a name="Typemaps_nn5"></a>10.1.3 Pattern matching</H3> |
| |
| |
| <p> |
| As the name implies, the purpose of a typemap is to "map" C datatypes to |
| types in the target language. Once a typemap is defined for a C datatype, |
| it is applied to all future occurrences of that type in the input file. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Convert from Perl --> C */ |
| %typemap(in) <b>int</b> { |
| $1 = SvIV($input); |
| } |
| |
| ... |
| int factorial(<b>int</b> n); |
| int gcd(<b>int</b> x, <b>int</b> y); |
| int count(char *s, char *t, <b>int</b> max); |
| </pre> |
| </div> |
| |
| <p> |
| The matching of typemaps to C datatypes is more than a simple textual match. In fact, |
| typemaps are fully built into the underlying type system. Therefore, typemaps are |
| unaffected by <tt>typedef</tt>, namespaces, and other declarations that might hide the |
| underlying type. For example, you could have code like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Convert from Ruby--> C */ |
| %typemap(in) <b>int</b> { |
| $1 = NUM2INT($input); |
| } |
| ... |
| typedef int Integer; |
| namespace foo { |
| typedef Integer Number; |
| }; |
| |
| int foo(<b>int</b> x); |
| int bar(<b>Integer</b> y); |
| int spam(<b>foo::Number</b> a, <b>foo::Number</b> b); |
| </pre> |
| </div> |
| |
| <p> |
| In this case, the typemap is still applied to the proper arguments even though typenames don't always |
| match the text "int". This ability to track types is a critical part of SWIG--in fact, all |
| of the target language modules work merely define a set of typemaps for the basic types. Yet, it |
| is never necessary to write new typemaps for typenames introduced by <tt>typedef</tt>. |
| </p> |
| |
| <p> |
| In addition to tracking typenames, typemaps may also be specialized to match against a specific argument name. For |
| example, you could write a typemap like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) <b>double nonnegative</b> { |
| $1 = PyFloat_AsDouble($input); |
| if ($1 < 0) { |
| PyErr_SetString(PyExc_ValueError,"argument must be nonnegative."); |
| return NULL; |
| } |
| } |
| |
| ... |
| double sin(double x); |
| double cos(double x); |
| double sqrt(<b>double nonnegative</b>); |
| |
| typedef double Real; |
| double log(<b>Real nonnegative</b>); |
| ... |
| </pre> |
| </div> |
| |
| <p> |
| For certain tasks such as input argument conversion, typemaps can be defined for sequences of |
| consecutive arguments. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (<b>char *str, int len</b>) { |
| $1 = PyString_AsString($input); /* char *str */ |
| $2 = PyString_Size($input); /* int len */ |
| } |
| ... |
| int count(<b>char *str, int len</b>, char c); |
| </pre> |
| </div> |
| |
| <p> |
| In this case, a single input object is expanded into a pair of C arguments. This example also |
| provides a hint to the unusual variable naming scheme involving <tt>$1</tt>, <tt>$2</tt>, and so forth. |
| </p> |
| |
| <H3><a name="Typemaps_nn6"></a>10.1.4 Reusing typemaps</H3> |
| |
| |
| <p> |
| Typemaps are normally defined for specific type and argument name patterns. However, typemaps can also |
| be copied and reused. One way to do this is to use assignment like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) Integer = int; |
| %typemap(in) (char *buffer, int size) = (char *str, int len); |
| </pre> |
| </div> |
| |
| <p> |
| A more general form of copying is found in the <tt>%apply</tt> directive like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { |
| /* Convert an integer argument */ |
| ... |
| } |
| %typemap(out) int { |
| /* Return an integer value */ |
| ... |
| } |
| |
| /* Apply all of the integer typemaps to size_t */ |
| %apply int { size_t }; |
| </pre> |
| </div> |
| |
| <p> |
| <tt>%apply</tt> merely takes <em>all</em> of the typemaps that are defined for one type and |
| applies them to other types. Note: you can include a comma separated set of types in the |
| <tt>{ ... }</tt> part of <tt>%apply</tt>. |
| </p> |
| |
| <p> |
| It should be noted that it is not necessary to copy typemaps for types that are related by <tt>typedef</tt>. |
| For example, if you have this, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| typedef int size_t; |
| </pre> |
| </div> |
| |
| <p> |
| then SWIG already knows that the <tt>int</tt> typemaps apply. You don't have to do anything. |
| </p> |
| |
| <H3><a name="Typemaps_nn7"></a>10.1.5 What can be done with typemaps?</H3> |
| |
| |
| <p> |
| The primary use of typemaps is for defining wrapper generation behavior at the level |
| of individual C/C++ datatypes. There are currently six general categories of problems that |
| typemaps address: |
| </p> |
| |
| <p> |
| <b>Argument handling</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int foo(<b>int x, double y, char *s</b>); |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Input argument conversion ("in" typemap).</li> |
| <li>Input argument type checking ("typecheck" typemap).</li> |
| <li>Output argument handling ("argout" typemap).</li> |
| <li>Input argument value checking ("check" typemap).</li> |
| <li>Input argument initialization ("arginit" typemap).</li> |
| <li>Default arguments ("default" typemap).</li> |
| <li>Input argument resource management ("freearg" typemap).</li> |
| </ul> |
| |
| <p> |
| <b>Return value handling</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| <b>int</b> foo(int x, double y, char *s); |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Function return value conversion ("out" typemap).</li> |
| <li>Return value resource management ("ret" typemap).</li> |
| <li>Resource management for newly allocated objects ("newfree" typemap).</li> |
| </ul> |
| |
| <p> |
| <b>Exception handling</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| <b>int</b> foo(int x, double y, char *s) throw(<b>MemoryError, IndexError</b>); |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Handling of C++ exception specifications. ("throw" typemap).</li> |
| </ul> |
| |
| <p> |
| <b>Global variables</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| <b>int foo;</b> |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Assignment of a global variable. ("varin" typemap).</li> |
| <li>Reading a global variable. ("varout" typemap).</li> |
| </ul> |
| |
| <p> |
| <b>Member variables</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| struct Foo { |
| <b>int x[20]</b>; |
| }; |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Assignment of data to a class/structure member. ("memberin" typemap).</li> |
| </ul> |
| |
| <p> |
| <b>Constant creation</b> |
| </p> |
| |
| <div class="code"> |
| <pre> |
| #define FOO 3 |
| %constant int BAR = 42; |
| enum { ALE, LAGER, STOUT }; |
| </pre> |
| </div> |
| |
| <ul> |
| <li>Creation of constant values. ("consttab" or "constcode" typemap).</li> |
| </ul> |
| |
| <p> |
| Details of each of these typemaps will be covered shortly. Also, certain language modules may define additional |
| typemaps that expand upon this list. For example, the Java module defines a variety of typemaps for controlling additional |
| aspects of the Java bindings. Consult language specific documentation for further details. |
| </p> |
| |
| <H3><a name="Typemaps_nn8"></a>10.1.6 What can't be done with typemaps?</H3> |
| |
| |
| <p> |
| Typemaps can't be used to define properties that apply to C/C++ declarations as a whole. For example, |
| suppose you had a declaration like this, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| Foo *make_Foo(); |
| </pre> |
| </div> |
| |
| <p> |
| and you wanted to tell SWIG that <tt>make_Foo()</tt> returned a newly |
| allocated object (for the purposes of providing better memory |
| management). Clearly, this property of <tt>make_Foo()</tt> is |
| <em>not</em> a property that would be associated with the datatype |
| <tt>Foo *</tt> by itself. Therefore, a completely different SWIG |
| customization mechanism (<tt>%feature</tt>) is used for this purpose. Consult the <a |
| href="Customization.html#Customization">Customization Features</a> chapter for more |
| information about that. |
| </p> |
| |
| <p> |
| Typemaps also can't be used to rearrange or transform the order of arguments. For example, |
| if you had a function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| void foo(int, char *); |
| </pre> |
| </div> |
| |
| <p> |
| you can't use typemaps to interchange the arguments, allowing you to call the |
| function like this: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| foo("hello",3) # Reversed arguments |
| </pre> |
| </div> |
| |
| <p> |
| If you want to change the calling conventions of a function, write a helper |
| function instead. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %rename(foo) wrap_foo; |
| %inline %{ |
| void wrap_foo(char *s, int x) { |
| foo(x,s); |
| } |
| %} |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn9"></a>10.1.7 The rest of this chapter</H3> |
| |
| |
| <p> |
| The rest of this chapter provides detailed information for people who |
| want to write new typemaps. This information is of particular importance to anyone |
| who intends to write a new SWIG target language module. Power users can also |
| use this information to write application specific type conversion rules. |
| </p> |
| |
| <p> |
| Since typemaps are strongly tied to the underlying C++ type system, |
| subsequent sections assume that you are reasonably familiar with the |
| basic details of values, pointers, references, arrays, type qualifiers |
| (e.g., <tt>const</tt>), structures, namespaces, templates, and memory |
| management in C/C++. If not, you would be well-advised to consult a copy |
| of "The C Programming Language" by Kernighan and Ritchie or |
| "The C++ Programming Language" by Stroustrup before going any further. |
| </p> |
| |
| <H2><a name="Typemaps_nn10"></a>10.2 Typemap specifications</H2> |
| |
| |
| <p> |
| This section describes the behavior of the <tt>%typemap</tt> directive itself. |
| </p> |
| |
| <H3><a name="Typemaps_nn11"></a>10.2.1 Defining a typemap</H3> |
| |
| |
| <p> |
| New typemaps are defined using the <tt>%typemap</tt> declaration. The general form of |
| this declaration is as follows (parts enclosed in [ ... ] are optional): |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(<em>method</em> [, <em>modifiers</em>]) <em>typelist</em> <em>code</em> ; |
| </pre> |
| </div> |
| |
| <p> |
| <em>method</em> is a simply a name that specifies what kind of typemap is being defined. It |
| is usually a name like <tt>"in"</tt>, <tt>"out"</tt>, or <tt>"argout"</tt>. The purpose of |
| these methods is described later. |
| </p> |
| |
| <p> |
| <em>modifiers</em> is an optional comma separated list of <tt>name="value"</tt> values. These |
| are sometimes to attach extra information to a typemap and is often target-language dependent. |
| </p> |
| |
| <p> |
| <em>typelist</em> is a list of the C++ type patterns that the typemap will match. The general form of |
| this list is as follows: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| typelist : typepattern [, typepattern, typepattern, ... ] ; |
| |
| typepattern : type [ (parms) ] |
| | type name [ (parms) ] |
| | ( typelist ) [ (parms) ] |
| |
| </pre> |
| </div> |
| |
| <p> |
| Each type pattern is either a simple type, a simple type and argument name, or a list of types in the |
| case of multi-argument typemaps. In addition, each type pattern can be parameterized with a list of temporary |
| variables (parms). The purpose of these variables will be explained shortly. |
| </p> |
| |
| <p><em>code</em> specifies the code used in the typemap. |
| Usually this is C/C++ code, but in the statically typed target languages, such as Java and C#, this can contain target language code for certain typemaps. |
| It can take any one of the following forms: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| code : { ... } |
| | " ... " |
| | %{ ... %} |
| </pre> |
| </div> |
| |
| <p> |
| Note that the preprocessor will expand code within the {} delimiters, but not in the last two styles of delimiters, |
| see <a href="Preprocessor.html#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>. |
| Here are some examples of valid typemap specifications: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Simple typemap declarations */ |
| %typemap(in) int { |
| $1 = PyInt_AsLong($input); |
| } |
| %typemap(in) int "$1 = PyInt_AsLong($input);"; |
| %typemap(in) int %{ |
| $1 = PyInt_AsLong($input); |
| %} |
| |
| /* Typemap with extra argument name */ |
| %typemap(in) int nonnegative { |
| ... |
| } |
| |
| /* Multiple types in one typemap */ |
| %typemap(in) int, short, long { |
| $1 = SvIV($input); |
| } |
| |
| /* Typemap with modifiers */ |
| %typemap(in,doc="integer") int "$1 = gh_scm2int($input);"; |
| |
| /* Typemap applied to patterns of multiple arguments */ |
| %typemap(in) (char *str, int len), |
| (char *buffer, int size) |
| { |
| $1 = PyString_AsString($input); |
| $2 = PyString_Size($input); |
| } |
| |
| /* Typemap with extra pattern parameters */ |
| %typemap(in, numinputs=0) int *output (int temp), |
| long *output (long temp) |
| { |
| $1 = &temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Admittedly, it's not the most readable syntax at first glance. However, the purpose of the |
| individual pieces will become clear. |
| </p> |
| |
| <H3><a name="Typemaps_nn12"></a>10.2.2 Typemap scope</H3> |
| |
| |
| <p> |
| Once defined, a typemap remains in effect for all of the declarations that follow. A typemap may be redefined for |
| different sections of an input file. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // typemap1 |
| %typemap(in) int { |
| ... |
| } |
| |
| int fact(int); // typemap1 |
| int gcd(int x, int y); // typemap1 |
| |
| // typemap2 |
| %typemap(in) int { |
| ... |
| } |
| |
| int isprime(int); // typemap2 |
| </pre> |
| </div> |
| |
| <p> |
| One exception to the typemap scoping rules pertains to the <tt>%extend</tt> declaration. <tt>%extend</tt> is used to attach |
| new declarations to a class or structure definition. Because of this, all of the declarations in an <tt>%extend</tt> block are |
| subject to the typemap rules that are in effect at the point where the class itself is defined. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| class Foo { |
| ... |
| }; |
| |
| %typemap(in) int { |
| ... |
| } |
| |
| %extend Foo { |
| int blah(int x); // typemap has no effect. Declaration is attached to Foo which |
| // appears before the %typemap declaration. |
| }; |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn13"></a>10.2.3 Copying a typemap</H3> |
| |
| |
| <p> |
| A typemap is copied by using assignment. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) Integer = int; |
| </pre> |
| </div> |
| |
| <p> |
| or this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) Integer, Number, int32_t = int; |
| </pre> |
| </div> |
| |
| <p> |
| Types are often managed by a collection of different typemaps. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { ... } |
| %typemap(out) int { ... } |
| %typemap(varin) int { ... } |
| %typemap(varout) int { ... } |
| </pre> |
| </div> |
| |
| <p> |
| To copy all of these typemaps to a new type, use <tt>%apply</tt>. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %apply int { Integer }; // Copy all int typemaps to Integer |
| %apply int { Integer, Number }; // Copy all int typemaps to both Integer and Number |
| </pre> |
| </div> |
| |
| <p> |
| The patterns for <tt>%apply</tt> follow the same rules as for <tt>%typemap</tt>. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %apply int *output { Integer *output }; // Typemap with name |
| %apply (char *buf, int len) { (char *buffer, int size) }; // Multiple arguments |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn14"></a>10.2.4 Deleting a typemap</H3> |
| |
| |
| <p> |
| A typemap can be deleted by simply defining no code. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int; // Clears typemap for int |
| %typemap(in) int, long, short; // Clears typemap for int, long, short |
| %typemap(in) int *output; |
| </pre> |
| </div> |
| |
| <p> |
| The <tt>%clear</tt> directive clears all typemaps for a given type. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %clear int; // Removes all types for int |
| %clear int *output, long *output; |
| </pre> |
| </div> |
| |
| <p> |
| <b>Note:</b> Since SWIG's default behavior is defined by typemaps, clearing a fundamental type like |
| <tt>int</tt> will make that type unusable unless you also define a new set of typemaps immediately |
| after the clear operation. |
| </p> |
| |
| <H3><a name="Typemaps_nn15"></a>10.2.5 Placement of typemaps</H3> |
| |
| |
| <p> |
| Typemap declarations can be declared in the global scope, within a C++ namespace, and within a C++ class. For |
| example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { |
| ... |
| } |
| |
| namespace std { |
| class string; |
| %typemap(in) string { |
| ... |
| } |
| } |
| |
| class Bar { |
| public: |
| typedef const int & const_reference; |
| %typemap(out) const_reference { |
| ... |
| } |
| }; |
| </pre> |
| </div> |
| |
| <p> |
| When a typemap appears inside a namespace or class, it stays in effect until the end of the SWIG input |
| (just like before). However, the typemap takes the local scope into account. Therefore, this |
| code |
| </p> |
| |
| <div class="code"> |
| <pre> |
| namespace std { |
| class string; |
| %typemap(in) string { |
| ... |
| } |
| } |
| </pre> |
| </div> |
| |
| <p> |
| is really defining a typemap for the type <tt>std::string</tt>. You could have code like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| namespace std { |
| class string; |
| %typemap(in) string { /* std::string */ |
| ... |
| } |
| } |
| |
| namespace Foo { |
| class string; |
| %typemap(in) string { /* Foo::string */ |
| ... |
| } |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this case, there are two completely distinct typemaps that apply to two completely different |
| types (<tt>std::string</tt> and <tt>Foo::string</tt>). |
| </p> |
| |
| <p> |
| It should be noted that for scoping to work, SWIG has to know that <tt>string</tt> is a typename defined |
| within a particular namespace. In this example, this is done using the class declaration <tt>class string</tt>. |
| </p> |
| |
| <H2><a name="Typemaps_nn16"></a>10.3 Pattern matching rules</H2> |
| |
| |
| <p> |
| The section describes the pattern matching rules by which C datatypes are associated with typemaps. |
| </p> |
| |
| <H3><a name="Typemaps_nn17"></a>10.3.1 Basic matching rules</H3> |
| |
| |
| <p> |
| Typemaps are matched using both a type and a name (typically the name of a argument). For a given |
| <tt>TYPE NAME</tt> pair, the following rules are applied, in order, to find a match. The first typemap found |
| is used. |
| </p> |
| |
| <ul> |
| <li>Typemaps that exactly match <tt>TYPE</tt> and <tt>NAME</tt>. |
| <li>Typemaps that exactly match <tt>TYPE</tt> only. |
| </ul> |
| |
| <p> |
| If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), they are stripped and the following |
| checks are made: |
| </p> |
| |
| <ul> |
| <li>Typemaps that match the stripped <tt>TYPE</tt> and <tt>NAME</tt>. |
| <Li>Typemaps that match the stripped <tt>TYPE</tt> only. |
| </ul> |
| |
| <p> |
| If <tt>TYPE</tt> is an array. The following transformation is made: |
| </p> |
| |
| <ul> |
| <li>Replace all dimensions to <tt>[ANY]</tt> and look for a generic array typemap. |
| </ul> |
| |
| <p> |
| To illustrate, suppose that you had a function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int foo(const char *s); |
| </pre> |
| </div> |
| |
| <p> |
| To find a typemap for the argument <tt>const char *s</tt>, SWIG will search for the following typemaps: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| const char *s Exact type and name match |
| const char * Exact type match |
| char *s Type and name match (stripped qualifiers) |
| char * Type match (stripped qualifiers) |
| </pre> |
| </div> |
| |
| <p> |
| When more than one typemap rule might be defined, only the first match |
| found is actually used. Here is an example that |
| shows how some of the basic rules are applied: |
| </p> |
| |
| <div class="code"><pre> |
| %typemap(in) int *x { |
| ... typemap 1 |
| } |
| |
| %typemap(in) int * { |
| ... typemap 2 |
| } |
| |
| %typemap(in) const int *z { |
| ... typemap 3 |
| } |
| |
| %typemap(in) int [4] { |
| ... typemap 4 |
| } |
| |
| %typemap(in) int [ANY] { |
| ... typemap 5 |
| } |
| |
| void A(int *x); // int *x rule (typemap 1) |
| void B(int *y); // int * rule (typemap 2) |
| void C(const int *x); // int *x rule (typemap 1) |
| void D(const int *z); // int * rule (typemap 3) |
| void E(int x[4]); // int [4] rule (typemap 4) |
| void F(int x[1000]); // int [ANY] rule (typemap 5) |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn18"></a>10.3.2 Typedef reductions</H3> |
| |
| |
| <p> |
| If no match is found using the rules in the previous section, SWIG |
| applies a typedef reduction to the type and repeats the typemap search |
| for the reduced type. To illustrate, suppose you had code like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { |
| ... typemap 1 |
| } |
| |
| typedef int Integer; |
| void blah(Integer x); |
| </pre> |
| </div> |
| |
| <p> |
| To find the typemap for <tt>Integer x</tt>, SWIG will first search for the following |
| typemaps: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| Integer x |
| Integer |
| </pre> |
| </div> |
| |
| <p> |
| Finding no match, it then applies a reduction <tt>Integer -> int</tt> to the type and |
| repeats the search. |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| int x |
| int --> match: typemap 1 |
| </pre> |
| </div> |
| |
| <p> |
| Even though two types might be the same via typedef, SWIG allows typemaps to be defined |
| for each typename independently. This allows for interesting customization possibilities based |
| solely on the typename itself. For example, you could write code like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| typedef double pdouble; // Positive double |
| |
| // typemap 1 |
| %typemap(in) double { |
| ... get a double ... |
| } |
| // typemap 2 |
| %typemap(in) pdouble { |
| ... get a positive double ... |
| } |
| double sin(double x); // typemap 1 |
| pdouble sqrt(pdouble x); // typemap 2 |
| </pre> |
| </div> |
| |
| <p> |
| When reducing the type, only one typedef reduction is applied at a |
| time. The search process continues to apply reductions until a |
| match is found or until no more reductions can be made. |
| </p> |
| |
| <p> |
| For complicated types, the reduction process can generate a long list of patterns. Consider the following: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| typedef int Integer; |
| typedef Integer Row4[4]; |
| void foo(Row4 rows[10]); |
| </pre> |
| </div> |
| |
| <p> |
| To find a match for the <tt>Row4 rows[10]</tt> argument, SWIG would |
| check the following patterns, stopping only when it found a match: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| Row4 rows[10] |
| Row4 [10] |
| Row4 rows[ANY] |
| Row4 [ANY] |
| |
| # Reduce Row4 --> Integer[4] |
| Integer rows[10][4] |
| Integer [10][4] |
| Integer rows[ANY][ANY] |
| Integer [ANY][ANY] |
| |
| # Reduce Integer --> int |
| int rows[10][4] |
| int [10][4] |
| int rows[ANY][ANY] |
| int [ANY][ANY] |
| </pre> |
| </div> |
| |
| <p> |
| For parameterized types like templates, the situation is even more complicated. Suppose you had some declarations |
| like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| typedef int Integer; |
| typedef foo<Integer,Integer> fooii; |
| void blah(fooii *x); |
| </pre> |
| </div> |
| |
| <p> |
| In this case, the following typemap patterns are searched for the argument <tt>fooii *x</tt>: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| fooii *x |
| fooii * |
| |
| # Reduce fooii --> foo<Integer,Integer> |
| foo<Integer,Integer> *x |
| foo<Integer,Integer> * |
| |
| # Reduce Integer -> int |
| foo<int, Integer> *x |
| foo<int, Integer> * |
| |
| # Reduce Integer -> int |
| foo<int, int> *x |
| foo<int, int> * |
| </pre> |
| </div> |
| |
| <p> |
| Typemap reductions are always applied to the left-most type that appears. Only when no reductions can be made to the left-most |
| type are reductions made to other parts of the type. This behavior means that you could define a typemap for |
| <tt>foo<int,Integer></tt>, but a typemap for <tt>foo<Integer,int></tt> would never be matched. Admittedly, this |
| is rather esoteric--there's little practical reason to write a typemap quite like that. Of course, you could rely on this |
| to confuse your coworkers even more. |
| </p> |
| |
| <H3><a name="Typemaps_nn19"></a>10.3.3 Default typemaps</H3> |
| |
| |
| <p> |
| Most SWIG language modules use typemaps to define the default behavior of the C primitive types. This |
| is entirely straightforward. For example, a set of typemaps are written like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int "convert an int"; |
| %typemap(in) short "convert a short"; |
| %typemap(in) float "convert a float"; |
| ... |
| </pre> |
| </div> |
| |
| <p> |
| Since typemap matching follows all <tt>typedef</tt> declarations, any sort of type that is |
| mapped to a primitive type through <tt>typedef</tt> will be picked up by one of these primitive typemaps. |
| </p> |
| |
| <p> |
| The default behavior for pointers, arrays, references, and other kinds of types are handled by |
| specifying rules for variations of the reserved <tt>SWIGTYPE</tt> type. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) SWIGTYPE * { ... default pointer handling ... } |
| %typemap(in) SWIGTYPE & { ... default reference handling ... } |
| %typemap(in) SWIGTYPE [] { ... default array handling ... } |
| %typemap(in) enum SWIGTYPE { ... default handling for enum values ... } |
| %typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... } |
| </pre> |
| </div> |
| |
| <p> |
| These rules match any kind of pointer, reference, or array--even when |
| multiple levels of indirection or multiple array dimensions are used. |
| Therefore, if you wanted to change SWIG's default handling for all |
| types of pointers, you would simply redefine the rule for <tt>SWIGTYPE |
| *</tt>. |
| </p> |
| |
| <p> |
| Finally, the following typemap rule is used to match against simple types that don't match any other rules: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) SWIGTYPE { ... handle an unknown type ... } |
| </pre> |
| </div> |
| |
| <p> |
| This typemap is important because it is the rule that gets triggered |
| when call or return by value is used. For instance, if you have a |
| declaration like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| double dot_product(Vector a, Vector b); |
| </pre> |
| </div> |
| |
| <p> |
| The <tt>Vector</tt> type will usually just get matched against |
| <tt>SWIGTYPE</tt>. The default implementation of <tt>SWIGTYPE</tt> is |
| to convert the value into pointers (as described in chapter 3). |
| </p> |
| |
| <p> |
| By redefining <tt>SWIGTYPE</tt> it may be possible to implement other |
| behavior. For example, if you cleared all typemaps for |
| <tt>SWIGTYPE</tt>, SWIG simply won't wrap any unknown datatype (which might |
| be useful for debugging). Alternatively, you might modify SWIGTYPE to marshal |
| objects into strings instead of converting them to pointers. |
| </p> |
| |
| <p> |
| The best way to explore the default typemaps is to look at the ones |
| already defined for a particular language module. Typemaps |
| definitions are usually found in the SWIG library in a file such as |
| <tt>python.swg</tt>, <tt>tcl8.swg</tt>, etc. |
| </p> |
| |
| <H3><a name="Typemaps_mixed_default"></a>10.3.4 Mixed default typemaps</H3> |
| |
| |
| <p> |
| The default typemaps described above can be mixed with <tt>const</tt> and with each other. |
| For example the <tt>SWIGTYPE *</tt> typemap is for default pointer handling, but if a <tt>const SWIGTYPE *</tt> typemap |
| is defined it will be used instead for constant pointers. Some further examples follow: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) enum SWIGTYPE & { ... enum references ... } |
| %typemap(in) const enum SWIGTYPE & { ... const enum references ... } |
| %typemap(in) SWIGTYPE *& { ... pointers passed by reference ... } |
| %typemap(in) SWIGTYPE * const & { ... constant pointers passed by reference ... } |
| %typemap(in) SWIGTYPE[ANY][ANY] { ... 2D arrays ... } |
| </pre> |
| </div> |
| |
| <p> |
| Note that the the typedef reduction described earlier is also used with these mixed default typemaps. |
| For example, say the following typemaps are defined and SWIG is looking for the best match for the enum shown below: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) const Hello & { ... } |
| %typemap(in) const enum SWIGTYPE & { ... } |
| %typemap(in) enum SWIGTYPE & { ... } |
| %typemap(in) SWIGTYPE & { ... } |
| %typemap(in) SWIGTYPE { ... } |
| |
| enum Hello {}; |
| const Hello &hi; |
| </pre> |
| </div> |
| |
| <p> |
| The typemap at the top of the list will be chosen, not because it is defined first, but because it is the closest match for the type being wrapped. |
| If any of the typemaps in the above list were not defined, then the next one on the list would have precedence. |
| In other words the typemap chosen is the closest explicit match. |
| </p> |
| |
| <p> |
| <b>Compatibility note: </b> The mixed default typemaps were introduced in SWIG-1.3.23, but were not used much in this version. |
| Expect to see them being used more and more within the various libraries in later versions of SWIG. |
| </p> |
| |
| |
| <H3><a name="Typemaps_nn20"></a>10.3.5 Multi-arguments typemaps</H3> |
| |
| |
| <p> |
| When multi-argument typemaps are specified, they take precedence over |
| any typemaps specified for a single type. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (char *buffer, int len) { |
| // typemap 1 |
| } |
| |
| %typemap(in) char *buffer { |
| // typemap 2 |
| } |
| |
| void foo(char *buffer, int len, int count); // (char *buffer, int len) |
| void bar(char *buffer, int blah); // char *buffer |
| </pre> |
| </div> |
| |
| <p> |
| Multi-argument typemaps are also more restrictive in the way that they are matched. |
| Currently, the first argument follows the matching rules described in the previous section, |
| but all subsequent arguments must match exactly. |
| </p> |
| |
| |
| <H2><a name="Typemaps_nn21"></a>10.4 Code generation rules</H2> |
| |
| |
| <p> |
| This section describes rules by which typemap code is inserted into |
| the generated wrapper code. |
| </p> |
| |
| <H3><a name="Typemaps_nn22"></a>10.4.1 Scope</H3> |
| |
| |
| <p> |
| When a typemap is defined like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { |
| $1 = PyInt_AsLong($input); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| the typemap code is inserted into the wrapper function using a new block scope. In other words, the |
| wrapper code will look like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| wrap_whatever() { |
| ... |
| // Typemap code |
| { |
| arg1 = PyInt_AsLong(obj1); |
| } |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Because the typemap code is enclosed in its own block, it is legal to declare temporary variables |
| for use during typemap execution. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) short { |
| long temp; /* Temporary value */ |
| if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) { |
| return TCL_ERROR; |
| } |
| $1 = (short) temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Of course, any variables that you declare inside a typemap are destroyed as soon as the typemap |
| code has executed (they are not visible to other parts of the wrapper function or other typemaps |
| that might use the same variable names). |
| </p> |
| |
| <p> |
| Occasionally, typemap code will be specified using a few alternative forms. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int "$1 = PyInt_AsLong($input);"; |
| %typemap(in) int %{ |
| $1 = PyInt_AsLong($input); |
| %} |
| </pre> |
| </div> |
| |
| <p> |
| These two forms are mainly used for cosmetics--the specified code is not enclosed inside |
| a block scope when it is emitted. This sometimes results in a less complicated looking wrapper function. |
| </p> |
| |
| <H3><a name="Typemaps_nn23"></a>10.4.2 Declaring new local variables</H3> |
| |
| |
| <p> |
| Sometimes it is useful to declare a new local variable that exists |
| within the scope of the entire wrapper function. A good example of this |
| might be an application in which you wanted to marshal strings. Suppose |
| you had a C++ function like this |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int foo(std::string *s); |
| </pre> |
| </div> |
| |
| <p> |
| and you wanted to pass a native string in the target language as an argument. For instance, |
| in Perl, you wanted the function to work like this: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| $x = foo("Hello World"); |
| </pre> |
| </div> |
| |
| <p> |
| To do this, you can't just pass a raw Perl string as the <tt>std::string *</tt> argument. |
| Instead, you have to create a temporary <tt>std::string</tt> object, copy the Perl string data into it, and |
| then pass a pointer to the object. To do this, simply specify the typemap with an extra parameter like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) std::string * <b>(std::string temp)</b> { |
| unsigned int len; |
| char *s; |
| s = SvPV($input,len); /* Extract string data */ |
| temp.assign(s,len); /* Assign to temp */ |
| $1 = &temp; /* Set argument to point to temp */ |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this case, <tt>temp</tt> becomes a local variable in |
| the scope of the entire wrapper function. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| wrap_foo() { |
| std::string temp; <--- Declaration of temp goes here |
| ... |
| |
| /* Typemap code */ |
| { |
| ... |
| temp.assign(s,len); |
| ... |
| } |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| When you set <tt>temp</tt> to a value, it |
| persists for the duration of the wrapper function and gets |
| cleaned up automatically on exit. |
| </p> |
| |
| <p> |
| It is perfectly safe to use more than one typemap involving local |
| variables in the same declaration. For example, you could declare a |
| function as :</p> |
| |
| <div class="code"><pre> |
| void foo(std::string *x, std::string *y, std::string *z); |
| </pre></div> |
| |
| <p> |
| This is safely handled because SWIG actually renames all local |
| variable references by appending an argument number suffix. Therefore, the |
| generated code would actually look like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| wrap_foo() { |
| int *arg1; /* Actual arguments */ |
| int *arg2; |
| int *arg3; |
| std::string temp1; /* Locals declared in the typemap */ |
| std::string temp2; |
| std::string temp3; |
| ... |
| { |
| char *s; |
| unsigned int len; |
| ... |
| temp1.assign(s,len); |
| arg1 = *temp1; |
| } |
| { |
| char *s; |
| unsigned int len; |
| ... |
| temp2.assign(s,len); |
| arg2 = &temp2; |
| } |
| { |
| char *s; |
| unsigned int len; |
| ... |
| temp3.assign(s,len); |
| arg3 = &temp3; |
| } |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Some typemaps do not recognize local variables (or they may simply not |
| apply). At this time, only typemaps that apply to argument conversion support this. |
| </p> |
| |
| <p> |
| <b>Note:</b> |
| </p> |
| |
| <p> |
| When declaring a typemap for multiple types, |
| each type must have its own local variable declaration. |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) const std::string *, std::string * (std::string temp) // NO! |
| // only std::string * has a local variable |
| // const std::string * does not (oops) |
| .... |
| |
| %typemap(in) const std::string * (std::string temp), std::string * (std::string temp) // Correct |
| .... |
| </pre> |
| </div> |
| |
| |
| <H3><a name="Typemaps_special_variables"></a>10.4.3 Special variables</H3> |
| |
| |
| <p> |
| Within all typemaps, the following special variables are expanded. |
| </p> |
| |
| <center> |
| <table border=1 summary="Typemap special variables"> |
| <tr><th>Variable</th><th>Meaning</th></tr> |
| |
| <tr> |
| <td>$<em>n</em></td> |
| <td> |
| A C local variable corresponding to type <em>n</em> in the typemap |
| pattern. |
| </td> |
| </tr> |
| |
| <tr> |
| <td>$argnum</td> |
| <td>Argument number. Only available in typemaps related to argument conversion</td> |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_name</td> |
| <td>Argument name</td> |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_type</td> |
| <td>Real C datatype of type <em>n</em>.</td> |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_ltype</td> |
| <td>ltype of type <em>n</em></td> |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_mangle</td> |
| <td>Mangled form of type <em>n</em>. For example <tt>_p_Foo</tt></td> |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_descriptor</td> |
| <td>Type descriptor structure for type <em>n</em>. For example |
| <tt>SWIGTYPE_p_Foo</tt>. This is primarily used when interacting with the |
| run-time type checker (described later).</td> |
| </tr> |
| |
| |
| <tr> |
| <td>$*<em>n</em>_type</td> |
| <td>Real C datatype of type <em>n</em> with one pointer removed.</td> |
| </tr> |
| |
| <tr> |
| <td>$*<em>n</em>_ltype</td> |
| <td>ltype of type <em>n</em> with one pointer removed.</td> |
| </tr> |
| |
| <tr> |
| <td>$*<em>n</em>_mangle</td> |
| <td>Mangled form of type <em>n</em> with one pointer removed. </td> |
| </tr> |
| |
| <tr> |
| <td>$*<em>n</em>_descriptor</td> |
| <td>Type descriptor structure for type <em>n</em> with one pointer removed. |
| </tr> |
| |
| |
| <tr> |
| <td>$&<em>n</em>_type</td> |
| <td>Real C datatype of type <em>n</em> with one pointer added.</td> |
| </tr> |
| |
| <tr> |
| <td>$&<em>n</em>_ltype</td> |
| <td>ltype of type <em>n</em> with one pointer added.</td> |
| </tr> |
| |
| <tr> |
| <td>$&<em>n</em>_mangle</td> |
| <td>Mangled form of type <em>n</em> with one pointer added.</td> |
| </tr> |
| |
| <tr> |
| <td>$&<em>n</em>_descriptor</td> |
| <td>Type descriptor structure for type <em>n</em> with one pointer added. |
| </tr> |
| |
| <tr> |
| <td>$<em>n</em>_basetype</td> |
| <td>Base typename with all pointers and qualifiers stripped. |
| </td> |
| </tr> |
| |
| </table> |
| </center> |
| |
| <p> |
| Within the table, $<em>n</em> refers to a specific type within the typemap specification. For example, |
| if you write this |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int *INPUT { |
| |
| } |
| </pre> |
| </div> |
| |
| <p> |
| then $1 refers to <tt>int *INPUT</tt>. If you have a typemap like this, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (int argc, char *argv[]) { |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| then $1 refers to <tt>int argc</tt> and $2 refers to <tt>char *argv[]</tt>. |
| </p> |
| |
| <p> |
| Substitutions related to types and names always fill in values from the actual code that was matched. |
| This is useful when a typemap might match multiple C datatype. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int, short, long { |
| $1 = ($1_ltype) PyInt_AsLong($input); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this case, <tt>$1_ltype</tt> is replaced with the datatype that is actually matched. |
| </p> |
| |
| |
| <p> |
| When typemap code is emitted, the C/C++ datatype of the special variables <tt>$1</tt> and |
| <tt>$2</tt> is always an "ltype." An "ltype" is simply a type that can legally appear |
| on the left-hand side of a C assignment operation. Here are a few examples of types |
| and ltypes: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| type ltype |
| ------ ---------------- |
| int int |
| const int int |
| const int * int * |
| int [4] int * |
| int [4][5] int (*)[5] |
| </pre> |
| </div> |
| |
| <p> |
| In most cases a ltype is simply the C datatype with qualifiers stripped off. In addition, |
| arrays are converted into pointers. |
| </p> |
| |
| <p> |
| Variables such as <tt>$&1_type</tt> and <tt>$*1_type</tt> are used to |
| safely modify the type by removing or adding pointers. Although not |
| needed in most typemaps, these substitutions are sometimes needed to properly |
| work with typemaps that convert values between pointers and values. |
| </p> |
| |
| <p> |
| If necessary, type related substitutions can also be used when declaring locals. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int * ($*1_type temp) { |
| temp = PyInt_AsLong($input); |
| $1 = &temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| There is one word of caution about declaring local variables in this manner. If you declare a local variable |
| using a type substitution such as <tt>$1_ltype temp</tt>, it won't work like you expect for arrays and certain |
| kinds of pointers. For example, if you wrote this, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int [10][20] { |
| $1_ltype temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| then the declaration of <tt>temp</tt> will be expanded as |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int (*)[20] temp; |
| </pre> |
| </div> |
| |
| <p> |
| This is illegal C syntax and won't compile. There is currently no |
| straightforward way to work around this problem in SWIG due to the way |
| that typemap code is expanded and processed. However, one possible workaround |
| is to simply pick an alternative type such as <tt>void *</tt> and use |
| casts to get the correct type when needed. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int [10][20] { |
| void *temp; |
| ... |
| (($1_ltype) temp)[i][j] = x; /* set a value */ |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Another approach, which only works for arrays is to use the <tt>$1_basetype</tt> substitution. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int [10][20] { |
| $1_basetype temp[10][20]; |
| ... |
| temp[i][j] = x; /* set a value */ |
| ... |
| } |
| </pre> |
| </div> |
| |
| <H2><a name="Typemaps_nn25"></a>10.5 Common typemap methods</H2> |
| |
| |
| <p> |
| The set of typemaps recognized by a language module may vary. However, |
| the following typemap methods are nearly universal: |
| </p> |
| |
| <H3><a name="Typemaps_nn26"></a>10.5.1 "in" typemap</H3> |
| |
| |
| <p> |
| The "in" typemap is used to convert function arguments from the target language |
| to C. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int { |
| $1 = PyInt_AsLong($input); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The following special variables are available: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| $input - Input object holding value to be converted. |
| $symname - Name of function/method being wrapped |
| </pre> |
| </div> |
| |
| <p> |
| This is probably the most commonly redefined typemap because it can be used |
| to implement customized conversions. |
| </p> |
| |
| <p> |
| In addition, the "in" typemap allows the number of converted arguments to be |
| specified. The <tt>numinputs</tt> attributes facilitates this. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // Ignored argument. |
| %typemap(in, numinputs=0) int *out (int temp) { |
| $1 = &temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| At this time, only zero or one arguments may be converted. |
| When <tt>numinputs</tt> is set to 0, the argument is effectively ignored and cannot be supplied from the target language. |
| The argument is still required when making the C/C++ call and the above typemap |
| shows the value used is instead obtained from a locally declared variable called <tt>temp</tt>. |
| Usually <tt>numinputs</tt> is not specified, whereupon the default value is 1, that is, there is a one to one mapping of the number of arguments when used from the target language to the C/C++ call. |
| <a href="#Typemaps_multi_argument_typemaps">Multi-argument typemaps</a> provide a similar concept where the number of arguments mapped from the target language to C/C++ can be changed for more tha multiple adjacent C/C++ arguments. |
| </p> |
| |
| <p> |
| <b>Compatibility note: </b> Specifying <tt>numinputs=0</tt> |
| is the same as the old "ignore" typemap. |
| </p> |
| |
| <H3><a name="Typemaps_nn27"></a>10.5.2 "typecheck" typemap</H3> |
| |
| |
| <p> |
| The "typecheck" typemap is used to support overloaded functions and methods. It merely checks an argument |
| to see whether or not it matches a specific type. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) int { |
| $1 = PyInt_Check($input) ? 1 : 0; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| For typechecking, the $1 variable is always a simple integer that is set to 1 or 0 depending on whether or not |
| the input argument is the correct type. |
| </p> |
| |
| <p> |
| If you define new "in" typemaps <em>and</em> your program uses overloaded methods, you should also define a collection of |
| "typecheck" typemaps. More details about this follow in a later section on "Typemaps and Overloading." |
| </p> |
| |
| <H3><a name="Typemaps_nn28"></a>10.5.3 "out" typemap</H3> |
| |
| |
| <p> |
| The "out" typemap is used to convert function/method return values from C |
| into the target language. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(out) int { |
| $result = PyInt_FromLong($1); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The following special variables are available. |
| </p> |
| |
| <div class="code"> |
| <pre> |
| $result - Result object returned to target language. |
| $symname - Name of function/method being wrapped |
| </pre> |
| </div> |
| |
| <p> |
| The "out" typemap supports an optional attribute flag called "optimal". This is for code optimisation and is detailed in the <a href="#Typemaps_optimal">Optimal code generation when returning by value</a> section. |
| </p> |
| |
| <H3><a name="Typemaps_nn29"></a>10.5.4 "arginit" typemap</H3> |
| |
| |
| <p> |
| The "arginit" typemap is used to set the initial value of a function |
| argument--before any conversion has occurred. This is not normally |
| necessary, but might be useful in highly specialized applications. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // Set argument to NULL before any conversion occurs |
| %typemap(arginit) int *data { |
| $1 = NULL; |
| } |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn30"></a>10.5.5 "default" typemap</H3> |
| |
| |
| <p> |
| The "default" typemap is used to turn an argument into a default |
| argument. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(default) int flags { |
| $1 = DEFAULT_FLAGS; |
| } |
| ... |
| int foo(int x, int y, int flags); |
| </pre> |
| </div> |
| |
| <p> |
| The primary use of this typemap is to either change the wrapping of |
| default arguments or specify a default argument in a language where |
| they aren't supported (like C). Target languages that do not support |
| optional arguments, such as Java and C#, effectively ignore the value specified |
| by this typemap as all arguments must be given. |
| </p> |
| |
| <p> |
| Once a default typemap has been applied to an argument, all arguments |
| that follow must have default values. |
| See the <a href="SWIG.html#SWIG_default_args">Default/optional arguments</a> section |
| for further information on default argument wrapping. |
| </p> |
| |
| <H3><a name="Typemaps_nn31"></a>10.5.6 "check" typemap</H3> |
| |
| |
| <p> |
| The "check" typemap is used to supply value checking code during argument |
| conversion. The typemap is applied <em>after</em> arguments have been |
| converted. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(check) int positive { |
| if ($1 <= 0) { |
| SWIG_exception(SWIG_ValueError,"Expected positive value."); |
| } |
| } |
| </pre> |
| </div> |
| |
| <H3><a name="Typemaps_nn32"></a>10.5.7 "argout" typemap</H3> |
| |
| |
| <p> |
| The "argout" typemap is used to return values from arguments. This |
| is most commonly used to write wrappers for C/C++ functions that need |
| to return multiple values. The "argout" typemap is almost always combined |
| with an "in" typemap---possibly to ignore the input value. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Set the input argument to point to a temporary variable */ |
| %typemap(in, numinputs=0) int *out (int temp) { |
| $1 = &temp; |
| } |
| |
| %typemap(argout) int *out { |
| // Append output value $1 to $result |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The following special variables are available. |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| $result - Result object returned to target language. |
| $input - The original input object passed. |
| $symname - Name of function/method being wrapped |
| </pre> |
| </div> |
| |
| <p> |
| The code supplied to the "argout" typemap is always placed after |
| the "out" typemap. If multiple return values are used, the extra |
| return values are often appended to return value of the function. |
| </p> |
| |
| <p> |
| See the <tt>typemaps.i</tt> library for examples. |
| </p> |
| |
| <H3><a name="Typemaps_nn33"></a>10.5.8 "freearg" typemap</H3> |
| |
| |
| <p> |
| The "freearg" typemap is used to cleanup argument data. It is only |
| used when an argument might have allocated resources that need to be |
| cleaned up when the wrapper function exits. The "freearg" typemap |
| usually cleans up argument resources allocated by the "in" typemap. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // Get a list of integers |
| %typemap(in) int *items { |
| int nitems = Length($input); |
| $1 = (int *) malloc(sizeof(int)*nitems); |
| } |
| // Free the list |
| %typemap(freearg) int *items { |
| free($1); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The "freearg" typemap inserted at the end of the wrapper function, |
| just before control is returned back to the target language. This |
| code is also placed into a special variable <tt>$cleanup</tt> that may |
| be used in other typemaps whenever a wrapper function needs to abort |
| prematurely. |
| </p> |
| |
| <H3><a name="Typemaps_nn34"></a>10.5.9 "newfree" typemap</H3> |
| |
| |
| <p> |
| The "newfree" typemap is used in conjunction with the <tt>%newobject</tt> |
| directive and is used to deallocate memory used by the return result |
| of a function. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(newfree) string * { |
| delete $1; |
| } |
| %typemap(out) string * { |
| $result = PyString_FromString($1->c_str()); |
| } |
| ... |
| |
| %newobject foo; |
| ... |
| string *foo(); |
| </pre> |
| </div> |
| |
| <p> |
| See <a href="Customization.html#ownership">Object ownership and %newobject</a> for further details. |
| </p> |
| |
| <H3><a name="Typemaps_nn35"></a>10.5.10 "memberin" typemap</H3> |
| |
| |
| <p> |
| The "memberin" typemap is used to copy data from <em>an already converted input value</em> |
| into a structure member. It is typically used to handle array members and other special |
| cases. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(memberin) int [4] { |
| memmove($1, $input, 4*sizeof(int)); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| It is rarely necessary to write "memberin" typemaps---SWIG already provides |
| a default implementation for arrays, strings, and other objects. |
| </p> |
| |
| <H3><a name="Typemaps_nn36"></a>10.5.11 "varin" typemap</H3> |
| |
| |
| <p> |
| The "varin" typemap is used to convert objects in the target language to C for the |
| purposes of assigning to a C/C++ global variable. This is implementation specific. |
| </p> |
| |
| <H3><a name="Typemaps_nn37"></a>10.5.12 "varout" typemap</H3> |
| |
| |
| <p> |
| The "varout" typemap is used to convert a C/C++ object to an object in the target |
| language when reading a C/C++ global variable. This is implementation specific. |
| </p> |
| |
| <H3><a name="throws_typemap"></a>10.5.13 "throws" typemap</H3> |
| |
| |
| <p> |
| The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method. |
| It provides a default mechanism for handling C++ methods that have declared the exceptions they will throw. |
| The purpose of this typemap is to convert a C++ exception into an error or exception in the target language. |
| It is slightly different to the other typemaps as it is based around the exception type rather than the type of a parameter or variable. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(throws) const char * %{ |
| PyErr_SetString(PyExc_RuntimeError, $1); |
| SWIG_fail; |
| %} |
| void bar() throw (const char *); |
| </pre> |
| </div> |
| |
| <p> |
| As can be seen from the generated code below, SWIG generates an exception handler |
| with the catch block comprising the "throws" typemap content. |
| </p> |
| |
| <div class="code"> |
| <pre> |
| ... |
| try { |
| bar(); |
| } |
| catch(char const *_e) { |
| PyErr_SetString(PyExc_RuntimeError, _e); |
| SWIG_fail; |
| |
| } |
| ... |
| </pre> |
| </div> |
| |
| <p> |
| Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them. |
| For a neat way to handle these, see the <a href="Customization.html#exception">Exception handling with %exception</a> section. |
| </p> |
| |
| <H2><a name="Typemaps_nn39"></a>10.6 Some typemap examples</H2> |
| |
| |
| <p> |
| This section contains a few examples. Consult language module documentation |
| for more examples. |
| </p> |
| |
| <H3><a name="Typemaps_nn40"></a>10.6.1 Typemaps for arrays</H3> |
| |
| |
| <p> |
| A common use of typemaps is to provide support for C arrays appearing both as |
| arguments to functions and as structure members. |
| </p> |
| |
| <p> |
| For example, suppose you had a function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| void set_vector(int type, float value[4]); |
| </pre> |
| </div> |
| |
| <p> |
| If you wanted to handle <tt>float value[4]</tt> as a list of floats, you might write a typemap |
| similar to this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| |
| %typemap(in) float value[4] (float temp[4]) { |
| int i; |
| if (!PySequence_Check($input)) { |
| PyErr_SetString(PyExc_ValueError,"Expected a sequence"); |
| return NULL; |
| } |
| if (PySequence_Length($input) != 4) { |
| PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 4 elements"); |
| return NULL; |
| } |
| for (i = 0; i < 4; i++) { |
| PyObject *o = PySequence_GetItem($input,i); |
| if (PyNumber_Check(o)) { |
| temp[i] = (float) PyFloat_AsDouble(o); |
| } else { |
| PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); |
| return NULL; |
| } |
| } |
| $1 = temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this example, the variable <tt>temp</tt> allocates a small array on the |
| C stack. The typemap then populates this array and passes it to the underlying C function. |
| </p> |
| |
| <p> |
| When used from Python, the typemap allows the following type of function call: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> set_vector(type, [ 1, 2.5, 5, 20 ]) |
| </pre> |
| </div> |
| |
| <p> |
| If you wanted to generalize the typemap to apply to arrays of all dimensions you might write this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) float value[ANY] (float temp[$1_dim0]) { |
| int i; |
| if (!PySequence_Check($input)) { |
| PyErr_SetString(PyExc_ValueError,"Expected a sequence"); |
| return NULL; |
| } |
| if (PySequence_Length($input) != $1_dim0) { |
| PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); |
| return NULL; |
| } |
| for (i = 0; i < $1_dim0; i++) { |
| PyObject *o = PySequence_GetItem($input,i); |
| if (PyNumber_Check(o)) { |
| temp[i] = (float) PyFloat_AsDouble(o); |
| } else { |
| PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); |
| return NULL; |
| } |
| } |
| $1 = temp; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this example, the special variable <tt>$1_dim0</tt> is expanded with the actual |
| array dimensions. Multidimensional arrays can be matched in a similar manner. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) float matrix[ANY][ANY] (float temp[$1_dim0][$1_dim1]) { |
| ... convert a 2d array ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| For large arrays, it may be impractical to allocate storage on the stack using a temporary variable |
| as shown. To work with heap allocated data, the following technique can be used. |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) float value[ANY] { |
| int i; |
| if (!PySequence_Check($input)) { |
| PyErr_SetString(PyExc_ValueError,"Expected a sequence"); |
| return NULL; |
| } |
| if (PySequence_Length($input) != $1_dim0) { |
| PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); |
| return NULL; |
| } |
| $1 = (float *) malloc($1_dim0*sizeof(float)); |
| for (i = 0; i < $1_dim0; i++) { |
| PyObject *o = PySequence_GetItem($input,i); |
| if (PyNumber_Check(o)) { |
| $1[i] = (float) PyFloat_AsDouble(o); |
| } else { |
| PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); |
| free($1); |
| return NULL; |
| } |
| } |
| } |
| %typemap(freearg) float value[ANY] { |
| if ($1) free($1); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this case, an array is allocated using <tt>malloc</tt>. The <tt>freearg</tt> typemap is then used |
| to release the argument after the function has been called. |
| </p> |
| |
| <p> |
| Another common use of array typemaps is to provide support for array structure members. |
| Due to subtle differences between pointers and arrays in C, you can't just "assign" to |
| a array structure member. Instead, you have to explicitly copy elements into the array. |
| For example, suppose you had a structure like this: |
| </p> |
| |
| <div class="code"><pre> |
| struct SomeObject { |
| float value[4]; |
| ... |
| }; |
| </pre></div> |
| |
| <p> |
| When SWIG runs, it won't produce any code to set the <tt>vec</tt> member. |
| You may even get a warning message like this: |
| </p> |
| |
| <div class="shell"><pre> |
| swig -python example.i |
| Generating wrappers for Python |
| example.i:10. Warning. Array member value will be read-only. |
| </pre></div> |
| |
| <p> |
| These warning messages indicate that SWIG does not know how you want |
| to set the <tt>vec</tt> field. |
| </p> |
| |
| <p> |
| To fix this, you can supply a special "memberin" typemap like this: |
| </p> |
| |
| <div class="code"><pre> |
| %typemap(memberin) float [ANY] { |
| int i; |
| for (i = 0; i < $1_dim0; i++) { |
| $1[i] = $input[i]; |
| } |
| } |
| </pre></div> |
| |
| <p> |
| The memberin typemap is used to set a structure member from data that has already been converted |
| from the target language to C. In this case, <tt>$input</tt> is the local variable in which |
| converted input data is stored. This typemap then copies this data into the structure. |
| </p> |
| |
| <p> |
| When combined with the earlier typemaps for arrays, the combination of the "in" and "memberin" typemap allows |
| the following usage: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> s = SomeObject() |
| >>> s.x = [1, 2.5, 5, 10] |
| </pre> |
| </div> |
| |
| <p> |
| Related to structure member input, it may be desirable to return structure members as a new kind of |
| object. For example, in this example, you will get very odd program behavior where the structure member |
| can be set nicely, but reading the member simply returns a pointer: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> s = SomeObject() |
| >>> s.x = [1, 2.5, 5, 10] |
| >>> print s.x |
| _1008fea8_p_float |
| >>> |
| </pre> |
| </div> |
| |
| <p> |
| To fix this, you can write an "out" typemap. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(out) float [ANY] { |
| int i; |
| $result = PyList_New($1_dim0); |
| for (i = 0; i < $1_dim0; i++) { |
| PyObject *o = PyFloat_FromDouble((double) $1[i]); |
| PyList_SetItem($result,i,o); |
| } |
| } |
| </pre> |
| </div> |
| |
| <p> |
| Now, you will find that member access is quite nice: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> s = SomeObject() |
| >>> s.x = [1, 2.5, 5, 10] |
| >>> print s.x |
| [ 1, 2.5, 5, 10] |
| </pre> |
| </div> |
| |
| <p> |
| <b>Compatibility Note:</b> SWIG1.1 used to provide a special "memberout" typemap. However, it was mostly |
| useless and has since been eliminated. To return structure members, simply use the "out" typemap. |
| </p> |
| |
| <H3><a name="Typemaps_nn41"></a>10.6.2 Implementing constraints with typemaps</H3> |
| |
| |
| <p> |
| One particularly interesting application of typemaps is the |
| implementation of argument constraints. This can be done with the |
| "check" typemap. When used, this allows you to provide code for |
| checking the values of function arguments. For example :</p> |
| |
| <div class="code"><pre> |
| %module math |
| |
| %typemap(check) double posdouble { |
| if ($1 < 0) { |
| croak("Expecting a positive number"); |
| } |
| } |
| |
| ... |
| double sqrt(double posdouble); |
| |
| </pre></div> |
| |
| <p> |
| This provides a sanity check to your wrapper function. If a negative |
| number is passed to this function, a Perl exception will be raised and |
| your program terminated with an error message.</p> |
| |
| <p> |
| This kind of checking can be particularly useful when working with |
| pointers. For example :</p> |
| |
| <div class="code"><pre> |
| %typemap(check) Vector * { |
| if ($1 == 0) { |
| PyErr_SetString(PyExc_TypeError,"NULL Pointer not allowed"); |
| return NULL; |
| } |
| } |
| |
| </pre></div> |
| |
| <p> |
| will prevent any function involving a <tt>Vector *</tt> from accepting |
| a NULL pointer. As a result, SWIG can often prevent a potential |
| segmentation faults or other run-time problems by raising an exception |
| rather than blindly passing values to the underlying C/C++ program.</p> |
| |
| <p> |
| Note: A more advanced constraint checking system is in development. Stay tuned. |
| </p> |
| |
| <H2><a name="Typemaps_nn43"></a>10.7 Typemaps for multiple languages</H2> |
| |
| |
| <p> |
| The code within typemaps is usually language dependent, |
| however, many languages support the same typemaps. |
| In order to distinguish typemaps across different languages, the preprocessor should be used. |
| For example, the "in" typemap for Perl and Ruby could be written as: |
| </p> |
| |
| <div class="code"><pre> |
| #if defined(SWIGPERL) |
| %typemap(in) int "$1 = ($1_ltype) SvIV($input);" |
| #elif defined(SWIGRUBY) |
| %typemap(in) int "$1 = NUM2INT($input);" |
| #else |
| #warning no "in" typemap defined |
| #endif |
| </pre></div> |
| |
| <p> |
| The full set of language specific macros is defined in the <a href="Preprocessor.html#Preprocessor_condition_compilation">Conditional Compilation</a> section. |
| The example above also shows a common approach of issuing a warning for an as yet unsupported language. |
| </p> |
| |
| <p> |
| <b>Compatibility note: </b> In SWIG-1.1 different languages could be distinguished with the language name being put within the <tt>%typemap</tt> directive, for example, <br> |
| <tt>%typemap(ruby,in) int "$1 = NUM2INT($input);"</tt>. |
| </p> |
| |
| <H2><a name="Typemaps_optimal"></a>10.8 Optimal code generation when returning by value</H2> |
| |
| |
| <p> |
| The "out" typemap is the main typemap for return types. |
| This typemap supports an optional attribute flag called "optimal", which is for reducing |
| temporary variables and the amount of generated code. |
| It only really makes a difference when returning objects by value and it cannot always be used, |
| as explained later on. |
| </p> |
| |
| <p> |
| When a function returns an object by value, SWIG generates code that instantiates the default |
| type on the stack then assigns the value returned by the function call to it. |
| A copy of this object is then made on the heap and this is what is ultimately stored and |
| used from the target language. |
| This will be clearer considering an example. |
| Consider running the following code through SWIG: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(out) SWIGTYPE %{ |
| $result = new $1_ltype((const $1_ltype &)$1); |
| %} |
| |
| %inline %{ |
| #include <iostream> |
| using namespace std; |
| |
| struct XX { |
| XX() { cout << "XX()" << endl; } |
| XX(int i) { cout << "XX(" << i << ")" << endl; } |
| XX(const XX &other) { cout << "XX(const XX &)" << endl; } |
| XX & operator =(const XX &other) { cout << "operator=(const XX &)" << endl; return *this; } |
| ~XX() { cout << "~XX()" << endl; } |
| static XX create() { |
| return XX(0); |
| } |
| }; |
| %} |
| </pre> |
| </div> |
| |
| <p> |
| The "out" typemap shown is the default typemap for C# when returning by objects by value. |
| When making a call to <tt>XX::create()</tt> from C#, the output is as follows: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| XX() |
| XX(0) |
| operator=(const XX &) |
| ~XX() |
| XX(const XX &) |
| ~XX() |
| ~XX() |
| </pre> |
| </div> |
| |
| <p> |
| Note that three objects are being created as well as an assignment. |
| Wouldn't it be great if the <tt>XX::create()</tt> method was the only time a constructor was called? |
| As the method returns by value, this is asking a lot and the code that SWIG generates by default |
| makes it impossible for the compiler to make this type of optimisation. |
| However, this is where the "optimal" attribute in the "out" typemap can help out. |
| If the typemap code is kept the same and just the "optimal" attribute specified like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(out, optimal="1") SWIGTYPE %{ |
| $result = new $1_ltype((const $1_ltype &)$1); |
| %} |
| </pre> |
| </div> |
| |
| <p> |
| then when the code is run again, the output is simply: |
| </P> |
| |
| <div class="targetlang"> |
| <pre> |
| XX(0) |
| ~XX() |
| </pre> |
| </div> |
| |
| <p> |
| How the "optimal" attribute works is best explained using the generated code. |
| Without "optimal", the generated code is: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() { |
| void * jresult ; |
| XX result; |
| result = XX::create(); |
| jresult = new XX((const XX &)result); |
| return jresult; |
| } |
| |
| </pre> |
| </div> |
| |
| <p> |
| With the "optimal" attribute, the code is: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() { |
| void * jresult ; |
| jresult = new XX((const XX &)XX::create()); |
| return jresult; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The major difference is the <tt>result</tt> temporary variable holding the value returned from <tt>XX::create()</tt> is no longer generated and instead the copy constructor call is made directly from |
| the value returned by <tt>XX::create()</tt>. |
| With modern compiler optimisations turned on, the copy is not actually done, in fact the object is never created |
| on the stack in <tt>XX::create()</tt> at all, it is simply created directly on the heap. |
| In the first instance, the <tt>$1</tt> special variable in the typemap is expanded into <tt>result</tt>. |
| In the second instance, <tt>$1</tt> is expanded into <tt>XX::create()</tt> and this is essentially |
| what the "optimal" attribute is telling SWIG to do. |
| </p> |
| |
| <p> |
| This kind of optimisation is not turned on by default as it has a number of restrictions. |
| Firstly, some code cannot be condensed into a simple call for passing into the copy constructor. |
| One common occurrence is when <a href="Customization.html#exception">%exception</a> is used. |
| Consider adding the following <tt>%exception</tt> to the example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %exception XX::create() %{ |
| try { |
| $action |
| } catch(const std::exception &e) { |
| cout << e.what() << endl; |
| } |
| %} |
| </pre> |
| </div> |
| |
| <p> |
| SWIG can detect when the "optimal" attribute cannot be used and will ignore it and in this case will issue the following warning: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| example.i:28: Warning(474): Method XX::create() usage of the optimal attribute in the out |
| typemap at example.i:14 ignored as the following cannot be used to generate optimal code: |
| try { |
| result = XX::create(); |
| } catch(const std::exception &e) { |
| cout << e.what() << endl; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| It should be clear that the above code cannot be used as the argument to the copy constructor call, ie for the <tt>$1</tt> substitution. |
| </p> |
| |
| <p> |
| Secondly, if the typemaps uses <tt>$1</tt> more than once, then multiple calls to the wrapped function |
| will be made. Obviously that is not very optimal. |
| In fact SWIG attempts to detect this and will issue a warning something like: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| example.i:21: Warning(475): Multiple calls to XX::create() might be generated due to |
| optimal attribute usage in the out typemap at example.i:7. |
| </pre> |
| </div> |
| |
| <p> |
| However, it doesn't always get it right, for example when <tt>$1</tt> is within some commented out code. |
| </p> |
| |
| <H2><a name="Typemaps_multi_argument_typemaps"></a>10.9 Multi-argument typemaps</H2> |
| |
| |
| <p> |
| So far, the typemaps presented have focused on the problem of dealing with |
| single values. For example, converting a single input object to a single argument |
| in a function call. However, certain conversion problems are difficult to handle |
| in this manner. As an example, consider the example at the very beginning of this |
| chapter: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int foo(int argc, char *argv[]); |
| </pre> |
| </div> |
| |
| <p> |
| Suppose that you wanted to wrap this function so that it accepted a single |
| list of strings like this: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> foo(["ale","lager","stout"]) |
| </pre> |
| </div> |
| |
| <p> |
| To do this, you not only need to map a list of strings to <tt> char *argv[]</tt>, but the |
| value of <tt>int argc</tt> is implicitly determined by the length of the list. Using only simple |
| typemaps, this type of conversion is possible, but extremely painful. Therefore, SWIG1.3 |
| introduces the notion of multi-argument typemaps. |
| </p> |
| |
| <p> |
| A multi-argument typemap is a conversion rule that specifies how to |
| convert a <em>single</em> object in the target language to set of |
| consecutive function arguments in C/C++. For example, the following multi-argument |
| maps perform the conversion described for the above example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (int argc, char *argv[]) { |
| int i; |
| if (!PyList_Check($input)) { |
| PyErr_SetString(PyExc_ValueError, "Expecting a list"); |
| return NULL; |
| } |
| $1 = PyList_Size($input); |
| $2 = (char **) malloc(($1+1)*sizeof(char *)); |
| for (i = 0; i < $1; i++) { |
| PyObject *s = PyList_GetItem($input,i); |
| if (!PyString_Check(s)) { |
| free($2); |
| PyErr_SetString(PyExc_ValueError, "List items must be strings"); |
| return NULL; |
| } |
| $2[i] = PyString_AsString(s); |
| } |
| $2[i] = 0; |
| } |
| |
| %typemap(freearg) (int argc, char *argv[]) { |
| if ($2) free($2); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| A multi-argument map is always specified by surrounding the arguments with parentheses as shown. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (int argc, char *argv[]) { ... } |
| </pre> |
| </div> |
| |
| <p> |
| Within the typemap code, the variables <tt>$1</tt>, <tt>$2</tt>, and so forth refer to each type |
| in the map. All of the usual substitutions apply--just use the appropriate <tt>$1</tt> or <tt>$2</tt> |
| prefix on the variable name (e.g., <tt>$2_type</tt>, <tt>$1_ltype</tt>, etc.) |
| </p> |
| |
| <p> |
| Multi-argument typemaps always have precedence over simple typemaps and SWIG always performs longest-match searching. |
| Therefore, you will get the following behavior: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int argc { ... typemap 1 ... } |
| %typemap(in) (int argc, char *argv[]) { ... typemap 2 ... } |
| %typemap(in) (int argc, char *argv[], char *env[]) { ... typemap 3 ... } |
| |
| int foo(int argc, char *argv[]); // Uses typemap 2 |
| int bar(int argc, int x); // Uses typemap 1 |
| int spam(int argc, char *argv[], char *env[]); // Uses typemap 3 |
| </pre> |
| </div> |
| |
| <p> |
| It should be stressed that multi-argument typemaps can appear anywhere in a function declaration and can |
| appear more than once. For example, you could write this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (int scount, char *swords[]) { ... } |
| %typemap(in) (int wcount, char *words[]) { ... } |
| |
| void search_words(int scount, char *swords[], int wcount, char *words[], int maxcount); |
| </pre> |
| </div> |
| |
| <p> |
| Other directives such as <tt>%apply</tt> and <tt>%clear</tt> also work with multi-argument maps. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %apply (int argc, char *argv[]) { |
| (int scount, char *swords[]), |
| (int wcount, char *words[]) |
| }; |
| ... |
| %clear (int scount, char *swords[]), (int wcount, char *words[]); |
| ... |
| </pre> |
| </div> |
| |
| <p> |
| Although multi-argument typemaps may seem like an exotic, little used feature, there |
| are several situations where they make sense. First, suppose you wanted to wrap |
| functions similar to the low-level <tt>read()</tt> and <tt>write()</tt> system calls. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| typedef unsigned int size_t; |
| |
| int read(int fd, void *rbuffer, size_t len); |
| int write(int fd, void *wbuffer, size_t len); |
| </pre> |
| </div> |
| |
| <p> |
| As is, the only way to use the functions would be to allocate memory and pass some kind of pointer |
| as the second argument---a process that might require the use of a helper function. However, using |
| multi-argument maps, the functions can be transformed into something more natural. For example, you |
| might write typemaps like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // typemap for an outgoing buffer |
| %typemap(in) (void *wbuffer, size_t len) { |
| if (!PyString_Check($input)) { |
| PyErr_SetString(PyExc_ValueError, "Expecting a string"); |
| return NULL; |
| } |
| $1 = (void *) PyString_AsString($input); |
| $2 = PyString_Size($input); |
| } |
| |
| // typemap for an incoming buffer |
| %typemap(in) (void *rbuffer, size_t len) { |
| if (!PyInt_Check($input)) { |
| PyErr_SetString(PyExc_ValueError, "Expecting an integer"); |
| return NULL; |
| } |
| $2 = PyInt_AsLong($input); |
| if ($2 < 0) { |
| PyErr_SetString(PyExc_ValueError, "Positive integer expected"); |
| return NULL; |
| } |
| $1 = (void *) malloc($2); |
| } |
| |
| // Return the buffer. Discarding any previous return result |
| %typemap(argout) (void *rbuffer, size_t len) { |
| Py_XDECREF($result); /* Blow away any previous result */ |
| if (result < 0) { /* Check for I/O error */ |
| free($1); |
| PyErr_SetFromErrno(PyExc_IOError); |
| return NULL; |
| } |
| $result = PyString_FromStringAndSize($1,result); |
| free($1); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| (note: In the above example, <tt>$result</tt> and <tt>result</tt> are two different variables. |
| <tt>result</tt> is the real C datatype that was returned by the function. <tt>$result</tt> is the |
| scripting language object being returned to the interpreter.). |
| </p> |
| |
| <p> |
| Now, in a script, you can write code that simply passes buffers as strings like this: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| >>> f = example.open("Makefile") |
| >>> example.read(f,40) |
| 'TOP = ../..\nSWIG = $(TOP)/.' |
| >>> example.read(f,40) |
| './swig\nSRCS = example.c\nTARGET ' |
| >>> example.close(f) |
| 0 |
| >>> g = example.open("foo", example.O_WRONLY | example.O_CREAT, 0644) |
| >>> example.write(g,"Hello world\n") |
| 12 |
| >>> example.write(g,"This is a test\n") |
| 15 |
| >>> example.close(g) |
| 0 |
| >>> |
| </pre> |
| </div> |
| |
| <p> |
| A number of multi-argument typemap problems also arise in libraries that |
| perform matrix-calculations--especially if they are mapped onto low-level Fortran |
| or C code. For example, you might have a function like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int is_symmetric(double *mat, int rows, int columns); |
| </pre> |
| </div> |
| |
| <p> |
| In this case, you might want to pass some kind of higher-level object as an matrix. To do |
| this, you could write a multi-argument typemap like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) (double *mat, int rows, int columns) { |
| MatrixObject *a; |
| a = GetMatrixFromObject($input); /* Get matrix somehow */ |
| |
| /* Get matrix properties */ |
| $1 = GetPointer(a); |
| $2 = GetRows(a); |
| $3 = GetColumns(a); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| This kind of technique can be used to hook into scripting-language matrix packages such as |
| Numeric Python. However, it should also be stressed that some care is in order. For example, |
| when crossing languages you may need to worry about issues such as row-major vs. column-major |
| ordering (and perform conversions if needed). |
| </p> |
| |
| <H2><a name="runtime_type_checker"></a>10.10 The run-time type checker</H2> |
| |
| |
| <p> |
| Most scripting languages need type information at run-time. This type information |
| can include how to construct types, how to garbage collect types, and the inheritance |
| relationships between types. If the language interface does not provide its own type |
| information storage, the generated SWIG code needs to provide it. |
| </p> |
| |
| <p> |
| Requirements for the type system: |
| </p> |
| <ul> |
| <li>Store inheritance and type equivalence information and be able to correctly |
| re-create the type pointer.</li> |
| <li>Share type information between modules.</li> |
| <li>Modules can be loaded in any order, irregardless of actual type |
| dependency.</li> |
| <li>Avoid the use of dynamically allocated memory, and library/system calls in general.</li> |
| <li>Provide a reasonably fast implementation, minimizing the lookup time for all |
| language modules.</li> |
| <li>Custom, language specific information can be attached to types.</li> |
| <li>Modules can be unloaded from the type system.</li> |
| </ul> |
| |
| <H3><a name="Typemaps_nn45"></a>10.10.1 Implementation</H3> |
| |
| |
| <p> |
| The run-time type checker is used by many, but not all, of SWIG's supported target languages. |
| The run-time type checker features |
| are not required and are thus not used for strongly typed languages such as Java and C#. |
| The scripting and scheme based languages rely on it and it forms |
| a critical part of SWIG's operation for these languages. |
| </p> |
| |
| <p> |
| When pointers, arrays, and objects are wrapped by SWIG, they are normally converted |
| into typed pointer objects. For example, an instance of <tt>Foo *</tt> might be |
| a string encoded like this: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| _108e688_p_Foo |
| </pre> |
| </div> |
| |
| <p> |
| At a basic level, the type checker simply restores some type-safety to |
| extension modules. However, the type checker is also responsible for |
| making sure that wrapped C++ classes are handled |
| correctly---especially when inheritance is used. This is especially |
| important when an extension module makes use of multiple inheritance. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| class Foo { |
| int x; |
| }; |
| |
| class Bar { |
| int y; |
| }; |
| |
| class FooBar : public Foo, public Bar { |
| int z; |
| }; |
| </pre> |
| </div> |
| |
| <p> |
| When the class <tt>FooBar</tt> is organized in memory, it contains the contents |
| of the classes <tt>Foo</tt> and <tt>Bar</tt> as well as its own data members. For example: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| FooBar --> | -----------| <-- Foo |
| | int x | |
| |------------| <-- Bar |
| | int y | |
| |------------| |
| | int z | |
| |------------| |
| </pre> |
| </div> |
| |
| <p> |
| Because of the way that base class data is stacked together, the |
| casting of a <tt>Foobar *</tt> to either of the base classes may |
| change the actual value of the pointer. This means that it is |
| generally not safe to represent pointers using a simple integer or a |
| bare <tt>void *</tt>---type tags are needed to implement correct |
| handling of pointer values (and to make adjustments when needed). |
| </p> |
| |
| <p> |
| In the wrapper code generated for each language, pointers are handled through |
| the use of special type descriptors and conversion functions. For example, |
| if you look at the wrapper code for Python, you will see code like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_Foo,1)) == -1) return NULL; |
| </pre> |
| </div> |
| |
| <p> |
| In this code, <tt>SWIGTYPE_p_Foo</tt> is the type descriptor that |
| describes <tt>Foo *</tt>. The type descriptor is actually a pointer to a |
| structure that contains information about the type name to use in the |
| target language, a list of equivalent typenames (via typedef or |
| inheritance), and pointer value handling information (if applicable). |
| The <tt>SWIG_ConvertPtr()</tt> function is simply a utility function |
| that takes a pointer object in the target language and a |
| type-descriptor objects and uses this information to generate a C++ |
| pointer. However, the exact name and calling conventions of the conversion |
| function depends on the target language (see language specific chapters for details). |
| </p> |
| |
| <p> |
| The actual type code is in swigrun.swg, and gets inserted near the top of the generated |
| swig wrapper file. The phrase "a type X that can cast into a type Y" means |
| that given a type X, it can be converted into a type Y. In other words, X is a derived |
| class of Y or X is a typedef of Y. The structure to store type information looks like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Structure to store information on one type */ |
| typedef struct swig_type_info { |
| const char *name; /* mangled name of this type */ |
| const char *str; /* human readable name for this type */ |
| swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ |
| struct swig_cast_info *cast; /* Linked list of types that can cast into this type */ |
| void *clientdata; /* Language specific type data */ |
| } swig_type_info; |
| |
| /* Structure to store a type and conversion function used for casting */ |
| typedef struct swig_cast_info { |
| swig_type_info *type; /* pointer to type that is equivalent to this type */ |
| swig_converter_func converter; /* function to cast the void pointers */ |
| struct swig_cast_info *next; /* pointer to next cast in linked list */ |
| struct swig_cast_info *prev; /* pointer to the previous cast */ |
| } swig_cast_info; |
| </pre> |
| </div> |
| |
| <p> |
| Each <tt>swig_type_info</tt> stores a linked list of types that it is equivalent to. Each entry in this |
| doubly linked list stores a pointer back to another swig_type_info structure, |
| along with a pointer to a conversion function. This conversion function is used |
| to solve the above problem of the FooBar class, correctly returning a pointer to |
| the type we want. |
| </p> |
| |
| <p> |
| The basic problem we need to solve is verifying and building arguments passed to functions. |
| So going back to the <tt>SWIG_ConvertPtr()</tt> function example from above, we are |
| expecting a <tt>Foo *</tt> and need to |
| check if <tt>obj0</tt> is in fact a <tt>Foo *</tt>. From before, <tt>SWIGTYPE_p_Foo</tt> is just |
| a pointer to the <tt>swig_type_info</tt> structure describing <tt>Foo *</tt>. So we loop through the |
| linked list of <tt>swig_cast_info</tt> structures attached to <tt>SWIGTYPE_p_Foo</tt>. If we see that the type of <tt>obj0</tt> is in the |
| linked list, we pass the object through the associated conversion function and |
| then return a positive. If we reach the end of the linked list without a match, |
| then <tt>obj0</tt> can not be converted to a <tt>Foo *</tt> and an error is generated. |
| </p> |
| |
| <p> |
| Another issue needing to be addressed is sharing type information between multiple modules. |
| More explicitly, we need |
| to have ONE <tt>swig_type_info</tt> for each type. If two modules both use the type, the |
| second module loaded must lookup and use the swig_type_info structure from the module already loaded. |
| Because no dynamic memory is used and the circular dependencies of the |
| casting information, loading the type information is somewhat tricky, and not explained here. |
| A complete description is in the <tt>Lib/swiginit.swg</tt> file (and near the top of any generated file). |
| </p> |
| |
| <p> |
| Each module has one swig_module_info structure which looks like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Structure used to store module information |
| * Each module generates one structure like this, and the runtime collects |
| * all of these structures and stores them in a circularly linked list.*/ |
| typedef struct swig_module_info { |
| swig_type_info **types; /* Array of pointers to swig_type_info structs in this module */ |
| int size; /* Number of types in this module */ |
| struct swig_module_info *next; /* Pointer to next element in circularly linked list */ |
| swig_type_info **type_initial; /* Array of initially generated type structures */ |
| swig_cast_info **cast_initial; /* Array of initially generated casting structures */ |
| void *clientdata; /* Language specific module data */ |
| } swig_module_info; |
| </pre> |
| </div> |
| |
| <p> |
| Each module stores an array of pointers to <tt>swig_type_info</tt> structures and the number of |
| types in this module. So when a second module is loaded, it finds the <tt>swig_module_info</tt> |
| structure for the first module and searches the array of types. If any of its own |
| types are in the first module and have already been loaded, it uses those <tt>swig_type_info</tt> |
| structures rather than creating new ones. These <tt>swig_module_info</tt> |
| structures are chained together in a circularly linked list. |
| </p> |
| |
| <H3><a name="Typemaps_nn46"></a>10.10.2 Usage</H3> |
| |
| |
| <p>This section covers how to use these functions from typemaps. To learn how to |
| call these functions from external files (not the generated _wrap.c file), see |
| the <a href="Modules.html#external_run_time">External access to the run-time system</a> |
| section.</p> |
| |
| <p>When pointers are converted in a typemap, the typemap code often looks |
| similar to this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) Foo * { |
| if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) return NULL; |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The most critical part is the typemap is the use of the <tt>$1_descriptor</tt> |
| special variable. When placed in a typemap, this is expanded into the |
| <tt>SWIGTYPE_*</tt> type descriptor object above. As a general rule, |
| you should always use <tt>$1_descriptor</tt> instead of trying to |
| hard-code the type descriptor name directly. |
| </p> |
| |
| <p> |
| There is another reason why you should always use the |
| <tt>$1_descriptor</tt> variable. When this special variable is |
| expanded, SWIG marks the corresponding type as "in use." When |
| type-tables and type information is emitted in the wrapper file, |
| descriptor information is only generated for those datatypes that were |
| actually used in the interface. This greatly reduces the size of the |
| type tables and improves efficiency. |
| </p> |
| |
| <p> |
| Occasionally, you might need to write a typemap that needs to convert |
| pointers of other types. To handle this, a special macro substitution |
| <tt>$descriptor(type)</tt> can be used to generate the SWIG type |
| descriptor name for any C datatype. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) Foo * { |
| if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) { |
| Bar *temp; |
| if ((SWIG_ConvertPtr($input, (void **) &temp, <b>$descriptor(Bar *)</b>) == -1) { |
| return NULL; |
| } |
| $1 = (Foo *) temp; |
| } |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The primary use of <tt>$descriptor(type)</tt> is when writing typemaps for container |
| objects and other complex data structures. There are some restrictions on the argument---namely it must |
| be a fully defined C datatype. It can not be any of the special typemap variables. |
| </p> |
| |
| <p> |
| In certain cases, SWIG may not generate type-descriptors like you expect. For example, |
| if you are converting pointers in some non-standard way or working with an unusual |
| combination of interface files and modules, you may find that SWIG omits information |
| for a specific type descriptor. To fix this, you may need to use the <tt>%types</tt> directive. |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %types(int *, short *, long *, float *, double *); |
| </pre> |
| </div> |
| |
| <p> |
| When <tt>%types</tt> is used, SWIG generates type-descriptor |
| information even if those datatypes never appear elsewhere in the |
| interface file. |
| </p> |
| |
| <p> |
| Further details about the run-time type checking can be found in the documentation for |
| individual language modules. Reading the source code may also help. The file |
| <tt>Lib/swigrun.swg</tt> in the SWIG library contains all of the source code for |
| type-checking. This code is also included in every generated wrapped file so you |
| probably just look at the output of SWIG to get a better sense for how types are |
| managed. |
| </p> |
| |
| <H2><a name="Typemaps_overloading"></a>10.11 Typemaps and overloading</H2> |
| |
| |
| <p> |
| In many target languages, SWIG fully supports C++ overloaded methods and functions. For example, |
| if you have a collection of functions like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| int foo(int x); |
| int foo(double x); |
| int foo(char *s, int y); |
| </pre> |
| </div> |
| |
| <p> |
| You can access the functions in a normal way from the scripting interpreter: |
| </p> |
| |
| <div class="targetlang"> |
| <pre> |
| # Python |
| foo(3) # foo(int) |
| foo(3.5) # foo(double) |
| foo("hello",5) # foo(char *, int) |
| |
| # Tcl |
| foo 3 # foo(int) |
| foo 3.5 # foo(double) |
| foo hello 5 # foo(char *, int) |
| </pre> |
| </div> |
| |
| <p> |
| To implement overloading, SWIG generates a separate wrapper function for each overloaded method. |
| For example, the above functions would produce something roughly like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // wrapper pseudocode |
| _wrap_foo_0(argc, args[]) { // foo(int) |
| int arg1; |
| int result; |
| ... |
| arg1 = FromInteger(args[0]); |
| result = foo(arg1); |
| return ToInteger(result); |
| } |
| |
| _wrap_foo_1(argc, args[]) { // foo(double) |
| double arg1; |
| int result; |
| ... |
| arg1 = FromDouble(args[0]); |
| result = foo(arg1); |
| return ToInteger(result); |
| } |
| |
| _wrap_foo_2(argc, args[]) { // foo(char *, int) |
| char *arg1; |
| int arg2; |
| int result; |
| ... |
| arg1 = FromString(args[0]); |
| arg2 = FromInteger(args[1]); |
| result = foo(arg1,arg2); |
| return ToInteger(result); |
| } |
| |
| </pre> |
| </div> |
| |
| <p> |
| Next, a dynamic dispatch function is generated: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| _wrap_foo(argc, args[]) { |
| if (argc == 1) { |
| if (IsInteger(args[0])) { |
| return _wrap_foo_0(argc,args); |
| } |
| if (IsDouble(args[0])) { |
| return _wrap_foo_1(argc,args); |
| } |
| } |
| if (argc == 2) { |
| if (IsString(args[0]) && IsInteger(args[1])) { |
| return _wrap_foo_2(argc,args); |
| } |
| } |
| error("No matching function!\n"); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| The purpose of the dynamic dispatch function is to select the appropriate C++ function based on |
| argument types---a task that must be performed at runtime in most of SWIG's target languages. |
| </p> |
| |
| <p> |
| The generation of the dynamic dispatch function is a relatively tricky affair. Not only must input typemaps |
| be taken into account (these typemaps can radically change the types of arguments accepted), but overloaded |
| methods must also be sorted and checked in a very specific order to resolve potential ambiguity. A high-level |
| overview of this ranking process is found in the "<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>" chapter. What isn't mentioned in that chapter |
| is the mechanism by which it is implemented---as a collection of typemaps. |
| </p> |
| |
| <p> |
| To support dynamic dispatch, SWIG first defines a general purpose type hierarchy as follows: |
| </p> |
| |
| <div class="diagram"> |
| <pre> |
| Symbolic Name Precedence Value |
| ------------------------------ ------------------ |
| SWIG_TYPECHECK_POINTER 0 |
| SWIG_TYPECHECK_VOIDPTR 10 |
| SWIG_TYPECHECK_BOOL 15 |
| SWIG_TYPECHECK_UINT8 20 |
| SWIG_TYPECHECK_INT8 25 |
| SWIG_TYPECHECK_UINT16 30 |
| SWIG_TYPECHECK_INT16 35 |
| SWIG_TYPECHECK_UINT32 40 |
| SWIG_TYPECHECK_INT32 45 |
| SWIG_TYPECHECK_UINT64 50 |
| SWIG_TYPECHECK_INT64 55 |
| SWIG_TYPECHECK_UINT128 60 |
| SWIG_TYPECHECK_INT128 65 |
| SWIG_TYPECHECK_INTEGER 70 |
| SWIG_TYPECHECK_FLOAT 80 |
| SWIG_TYPECHECK_DOUBLE 90 |
| SWIG_TYPECHECK_COMPLEX 100 |
| SWIG_TYPECHECK_UNICHAR 110 |
| SWIG_TYPECHECK_UNISTRING 120 |
| SWIG_TYPECHECK_CHAR 130 |
| SWIG_TYPECHECK_STRING 140 |
| SWIG_TYPECHECK_BOOL_ARRAY 1015 |
| SWIG_TYPECHECK_INT8_ARRAY 1025 |
| SWIG_TYPECHECK_INT16_ARRAY 1035 |
| SWIG_TYPECHECK_INT32_ARRAY 1045 |
| SWIG_TYPECHECK_INT64_ARRAY 1055 |
| SWIG_TYPECHECK_INT128_ARRAY 1065 |
| SWIG_TYPECHECK_FLOAT_ARRAY 1080 |
| SWIG_TYPECHECK_DOUBLE_ARRAY 1090 |
| SWIG_TYPECHECK_CHAR_ARRAY 1130 |
| SWIG_TYPECHECK_STRING_ARRAY 1140 |
| </pre> |
| </div> |
| |
| <p> |
| (These precedence levels are defined in <tt>swig.swg</tt>, a library file that's included by all target language modules.) |
| </p> |
| |
| <p> |
| In this table, the precedence-level determines the order in which types are going to be checked. Low values |
| are always checked before higher values. For example, integers are checked before floats, single values are checked |
| before arrays, and so forth. |
| </p> |
| |
| <p> |
| Using the above table as a guide, each target language defines a collection of "typecheck" typemaps. |
| The follow excerpt from the Python module illustrates this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| /* Python type checking rules */ |
| /* Note: %typecheck(X) is a macro for %typemap(typecheck,precedence=X) */ |
| |
| %typecheck(SWIG_TYPECHECK_INTEGER) |
| int, short, long, |
| unsigned int, unsigned short, unsigned long, |
| signed char, unsigned char, |
| long long, unsigned long long, |
| const int &, const short &, const long &, |
| const unsigned int &, const unsigned short &, const unsigned long &, |
| const long long &, const unsigned long long &, |
| enum SWIGTYPE, |
| bool, const bool & |
| { |
| $1 = (PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; |
| } |
| |
| %typecheck(SWIG_TYPECHECK_DOUBLE) |
| float, double, |
| const float &, const double & |
| { |
| $1 = (PyFloat_Check($input) || PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; |
| } |
| |
| %typecheck(SWIG_TYPECHECK_CHAR) char { |
| $1 = (PyString_Check($input) && (PyString_Size($input) == 1)) ? 1 : 0; |
| } |
| |
| %typecheck(SWIG_TYPECHECK_STRING) char * { |
| $1 = PyString_Check($input) ? 1 : 0; |
| } |
| |
| %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { |
| void *ptr; |
| if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == -1) { |
| $1 = 0; |
| PyErr_Clear(); |
| } else { |
| $1 = 1; |
| } |
| } |
| |
| %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { |
| void *ptr; |
| if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0) == -1) { |
| $1 = 0; |
| PyErr_Clear(); |
| } else { |
| $1 = 1; |
| } |
| } |
| |
| %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { |
| void *ptr; |
| if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == -1) { |
| $1 = 0; |
| PyErr_Clear(); |
| } else { |
| $1 = 1; |
| } |
| } |
| |
| %typecheck(SWIG_TYPECHECK_POINTER) PyObject * |
| { |
| $1 = ($input != 0); |
| } |
| </pre> |
| </div> |
| |
| <p> |
| It might take a bit of contemplation, but this code has merely organized all of the basic C++ types, provided some simple type-checking |
| code, and assigned each type a precedence value. |
| </p> |
| |
| <p> |
| Finally, to generate the dynamic dispatch function, SWIG uses the following algorithm: |
| </p> |
| |
| <ul> |
| <li>Overloaded methods are first sorted by the number of required arguments.</li> |
| <li>Methods with the same number of arguments are then sorted by precedence values of argument types.</li> |
| <li>Typecheck typemaps are then emitted to produce a dispatch function that checks arguments in the correct order.</li> |
| </ul> |
| |
| <p> |
| If you haven't written any typemaps of your own, it is unnecessary to worry about the typechecking rules. |
| However, if you have written new input typemaps, you might have to supply a typechecking rule as well. |
| An easy way to do this is to simply copy one of the existing typechecking rules. |
| Here is an example, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| // Typemap for a C++ string |
| %typemap(in) std::string { |
| if (PyString_Check($input)) { |
| $1 = std::string(PyString_AsString($input)); |
| } else { |
| SWIG_exception(SWIG_TypeError, "string expected"); |
| } |
| } |
| // Copy the typecheck code for "char *". |
| %typemap(typecheck) std::string = char *; |
| </pre> |
| </div> |
| |
| <p> |
| The bottom line: If you are writing new typemaps and you are using overloaded methods, you will probably |
| have to write typecheck code or copy existing code. Since this is a relatively new SWIG feature, there are |
| few examples to work with. However, you might look at some of the existing library files likes 'typemaps.i' for |
| a guide. |
| </p> |
| |
| <p> |
| <b>Notes:</b> |
| </p> |
| |
| <ul> |
| <li>Typecheck typemaps are not used for non-overloaded methods. Because of this, it is |
| still always necessary to check types in any "in" typemaps. |
| </li> |
| |
| <li>The dynamic dispatch process is only meant to be a heuristic. There are many corner |
| cases where SWIG simply can't disambiguate types to the same degree as C++. The only way to |
| resolve this ambiguity is to use the %rename directive to rename one of the overloaded methods (effectively |
| eliminating overloading). |
| </li> |
| |
| <li> |
| Typechecking may be partial. For example, if working with arrays, the typecheck code might |
| simply check the type of the first array element and use that to dispatch to the correct function. |
| Subsequent "in" typemaps would then perform more extensive type-checking. |
| </li> |
| |
| <li>Make sure you read the section on overloading in the "<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>" chapter. |
| </li> |
| </ul> |
| |
| <H2><a name="Typemaps_nn48"></a>10.12 More about <tt>%apply</tt> and <tt>%clear</tt></H2> |
| |
| |
| <p> |
| In order to implement certain kinds of program behavior, it is sometimes necessary to |
| write sets of typemaps. For example, to support output arguments, one often writes |
| a set of typemaps like this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in,numinputs=0) int *OUTPUT (int temp) { |
| $1 = &temp; |
| } |
| %typemap(argout) int *OUTPUT { |
| // return value somehow |
| } |
| </pre> |
| </div> |
| |
| <p> |
| To make it easier to apply the typemap to different argument types and names, the <tt>%apply</tt> directive |
| performs a copy of all typemaps from one type to another. For example, if you specify this, |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %apply int *OUTPUT { int *retvalue, int32 *output }; |
| </pre> |
| </div> |
| |
| <p> |
| then all of the <tt>int *OUTPUT</tt> typemaps are copied to <tt>int *retvalue</tt> and <tt>int32 *output</tt>. |
| </p> |
| |
| <p> |
| However, there is a subtle aspect of <tt>%apply</tt> that needs more description. Namely, <tt>%apply</tt> does not |
| overwrite a typemap rule if it is already defined for the target datatype. This behavior allows you to do two things: |
| </p> |
| |
| <ul> |
| <li>You can specialize parts of a complex typemap rule by first defining a few typemaps and then using |
| <tt>%apply</tt> to incorporate the remaining pieces. |
| </li> |
| |
| <li>Sets of different typemaps can be applied to the same datatype using repeated <tt>%apply</tt> directives. |
| </li> |
| </ul> |
| |
| <p> |
| For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int *INPUT (int temp) { |
| temp = ... get value from $input ...; |
| $1 = &temp; |
| } |
| |
| %typemap(check) int *POSITIVE { |
| if (*$1 <= 0) { |
| SWIG_exception(SWIG_ValueError,"Expected a positive number!\n"); |
| return NULL; |
| } |
| } |
| |
| ... |
| %apply int *INPUT { int *invalue }; |
| %apply int *POSITIVE { int *invalue }; |
| </pre> |
| </div> |
| |
| <p> |
| Since <tt>%apply</tt> does not overwrite or replace any existing rules, the only way to reset behavior is to |
| use the <tt>%clear</tt> directive. <tt>%clear</tt> removes all typemap rules defined for a specific datatype. For |
| example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %clear int *invalue; |
| </pre> |
| </div> |
| |
| <H2><a name="Typemaps_nn49"></a>10.13 Reducing wrapper code size</H2> |
| |
| |
| <p> |
| Since the code supplied to a typemap is inlined directly into wrapper functions, typemaps can result |
| in a tremendous amount of code bloat. For example, consider this typemap for an array: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) float [ANY] { |
| int i; |
| if (!PySequence_Check($input)) { |
| PyErr_SetString(PyExc_ValueError,"Expected a sequence"); |
| return NULL; |
| } |
| if (PySequence_Length($input) != $1_dim0) { |
| PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements"); |
| return NULL; |
| } |
| $1 = (float) malloc($1_dim0*sizeof(float)); |
| for (i = 0; i < $1_dim0; i++) { |
| PyObject *o = PySequence_GetItem($input,i); |
| if (PyNumber_Check(o)) { |
| $1[i] = (float) PyFloat_AsDouble(o); |
| } else { |
| PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); |
| free(result); |
| return NULL; |
| } |
| } |
| } |
| </pre> |
| </div> |
| |
| <p> |
| If you had a large interface with hundreds of functions all accepting |
| array parameters, this typemap would be replicated |
| repeatedly--generating a huge amount of code. A better approach might |
| be to consolidate some of the typemap into a function. For example: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %{ |
| /* Define a helper function */ |
| static float * |
| convert_float_array(PyObject *input, int size) { |
| int i; |
| float *result; |
| if (!PySequence_Check(input)) { |
| PyErr_SetString(PyExc_ValueError,"Expected a sequence"); |
| return NULL; |
| } |
| if (PySequence_Length(input) != size) { |
| PyErr_SetString(PyExc_ValueError,"Size mismatch. "); |
| return NULL; |
| } |
| result = (float) malloc(size*sizeof(float)); |
| for (i = 0; i < size; i++) { |
| PyObject *o = PySequence_GetItem(input,i); |
| if (PyNumber_Check(o)) { |
| result[i] = (float) PyFloat_AsDouble(o); |
| } else { |
| PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers"); |
| free(result); |
| return NULL; |
| } |
| } |
| return result; |
| } |
| %} |
| |
| %typemap(in) float [ANY] { |
| $1 = convert_float_array($input, $1_dim0); |
| if (!$1) return NULL; |
| } |
| %} |
| </pre> |
| </div> |
| |
| <H2><a name="Typemaps_nn47"></a>10.14 Passing data between typemaps</H2> |
| |
| |
| <p> |
| It is also important to note that the primary use of local variables |
| is to create stack-allocated objects for temporary use inside a |
| wrapper function (this is faster and less-prone to error than |
| allocating data on the heap). In general, the variables are not intended |
| to pass information between different types of typemaps. However, this |
| can be done if you realize that local names have the argument number appended |
| to them. For example, you could do this: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| %typemap(in) int *(int temp) { |
| temp = (int) PyInt_AsLong($input); |
| $1 = &temp; |
| } |
| |
| %typemap(argout) int * { |
| PyObject *o = PyInt_FromLong(temp$argnum); |
| ... |
| } |
| </pre> |
| </div> |
| |
| <p> |
| In this case, the <tt>$argnum</tt> variable is expanded into the argument |
| number. Therefore, the code will reference the appropriate local |
| such as <tt>temp1</tt> and <tt>temp2</tt>. It should be noted that there are |
| plenty of opportunities to break the universe here and that accessing locals |
| in this manner should probably be avoided. At the very least, you should make |
| sure that the typemaps sharing information have exactly the same types and names. |
| </p> |
| |
| |
| <H2><a name="Typemaps_nn51"></a>10.15 Where to go for more information?</H2> |
| |
| |
| <p> |
| The |
| best place to find out more information about writing typemaps is to |
| look in the SWIG library. Most language modules define all of their |
| default behavior using typemaps. These are found in files such as |
| <tt>python.swg</tt>, <tt>perl5.swg</tt>, <tt>tcl8.swg</tt> and so |
| forth. The <tt>typemaps.i</tt> file in the library also contains |
| numerous examples. You should look at these files to get a feel |
| for how to define typemaps of your own. |
| Some of the language modules support additional typemaps and further |
| information is available in the individual chapters for each target language. |
| </p> |
| |
| </body> |
| </html> |