diff options
Diffstat (limited to 'Doc/Manual/Typemaps.html')
| -rw-r--r-- | Doc/Manual/Typemaps.html | 4066 |
1 files changed, 4066 insertions, 0 deletions
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html new file mode 100644 index 0000000..da4fdad --- /dev/null +++ b/Doc/Manual/Typemaps.html @@ -0,0 +1,4066 @@ +<!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_defining">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_pattern_matching">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> +<li><a href="#Typemaps_special_variable_macros">Special variable macros</a> +<ul> +<li><a href="#Typemaps_special_macro_descriptor">$descriptor(type)</a> +<li><a href="#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a> +</ul> +</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_multi_argument_typemaps">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_runtime_type_checker_usage">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_nn52">C++ "this" pointer</a> +<li><a href="#Typemaps_nn51">Where to go for more information?</a> +</ul> +</div> +<!-- INDEX --> + + + +<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 code +that is inserted directly into the SWIG generated wrapper functions. +The code is usually C or C++ code which will be generated into the C/C++ wrapper functions. +Note that this isn't always the case as some target language modules allow target language +code within the typemaps which gets generated into target language specific files. +Within this code, a number of special variables prefixed with a $ are expanded. These are +really just placeholders for C/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/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/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_defining"></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_pattern_matching"></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. +This is by no means a complete list as some target languages have additional special variables which are documented in the language specific chapters. +</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> + +<H3><a name="Typemaps_special_variable_macros"></a>10.4.4 Special variable macros</H3> + + +<p> +Special variable macros are like macro functions in that they take one or more input arguments +which are used for the macro expansion. +They look like macro/function calls but use the special variable <tt>$</tt> prefix to the macro name. +Note that unlike normal macros, the expansion is not done by the preprocessor, +it is done during the SWIG parsing/compilation stages. +The following special variable macros are available across all language modules. +</p> + +<H4><a name="Typemaps_special_macro_descriptor"></a>10.4.4.1 $descriptor(type)</H4> + + +<p> +This macro expands into the type descriptor structure for any C/C++ type specified in <tt>type</tt>. +It behaves like the <tt>$1_descriptor</tt> special variable described above except that the type to expand is +taken from the macro argument rather than inferred from the typemap type. +For example, <tt>$descriptor(std::vector<int> *)</tt> will expand into <tt>SWIGTYPE_p_std__vectorT_int_t</tt>. +This macro is mostly used in the scripting target languages and is demonstrated later in the <a href="#Typemaps_runtime_type_checker_usage">Run-time type checker usage</a> section. +</p> + +<H4><a name="Typemaps_special_macro_typemap"></a>10.4.4.2 $typemap(method, typepattern)</H4> + + +<p> +This macro uses the <a href="#Typemaps_pattern_matching">pattern matching rules</a> described earlier to lookup and +then substitute the special variable macro with the code in the matched typemap. +The typemap to search for is specified by the arguments, where <tt>method</tt> is the typemap method name and +<tt>typepattern</tt> is a type pattern as per the <tt>%typemap</tt> specification in the <a href="#Typemaps_defining">Defining a typemap</a> section. +</p> + +<p> +The special variables within the matched typemap are expanded into those for the matched typemap type, +not the typemap within which the macro is called. +In practice, there is little use for this macro in the scripting target languages. +It is mostly used in the target languages that are statically typed as a way to obtain the target language type given the C/C++ type and more commonly only when the C++ type is a template parameter. +</p> + +<p> +The example below is for C# only and uses some typemap method names documented in the C# chapter, but it shows some of the possible syntax variations. +</p> + +<div class="code"> +<pre> +%typemap(cstype) unsigned long "uint" +%typemap(cstype) unsigned long bb "bool" +%typemap(cscode) BarClass %{ + void foo($typemap(cstype, unsigned long aa) var1, + $typemap(cstype, unsigned long bb) var2, + $typemap(cstype, (unsigned long bb)) var3, + $typemap(cstype, unsigned long) var4) + { + // do something + } +%} +</pre> +</div> + +<p> +The result is the following expansion +</p> + +<div class="code"> +<pre> +%typemap(cstype) unsigned long "uint" +%typemap(cstype) unsigned long bb "bool" +%typemap(cscode) BarClass %{ + void foo(uint var1, + bool var2, + bool var3, + uint var4) + { + // do something + } +%} +</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, thereby giving the compiler the opportunity to +use <i>return value optimization</i> for generating faster executing code. +It only really makes a difference when returning objects by value and has some limitations on usage, +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 use <i>return value optimisation (RVO)</i>. +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 compilers implementing RVO, 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> +The "optimal" attribute 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_runtime_type_checker_usage"></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, the special variable macro +<tt>$descriptor(type)</tt> covered earlier 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_nn52"></a>10.15 C++ "this" pointer</H2> + + +<p> +All the rules discussed for Typemaps apply to C++ as well as C. +However in addition C++ passes an extra parameter into every +non-static class method -- the <tt>this</tt> pointer. Occasionally it can be +useful to apply a typemap to this pointer (for example to check +and make sure <tt>this</tt> is non-null before deferencing). +Actually, C also has an the equivalent of the <tt>this</tt> pointer which is used +when accessing variables in a C struct. +</p> +<p> +In order to customise the <tt>this</tt> pointer handling, target a variable named <tt>self</tt> in your typemaps. +<tt>self</tt> is the name SWIG uses to refer to the extra parameter in wrapped functions. +</p> +<p> +For example, if wrapping for Java generation: +</p> + +<div class="code"> +<pre> +%typemap(check) SWIGTYPE *self %{ +if (!$1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "swigCPtr null"); + return $null; +} +%} +</pre> +</div> + +<p> +In the above case, the <tt>$1</tt> variable is expanded into the argument +name that SWIG is using as the <tt>this</tt> pointer. + +SWIG will then insert the check code before the actual C++ class method +is called, and will raise an exception rather than crash +the Java virtual machine. + +The generated code will look something like: +</p> + +<div class="code"> +<pre> + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, + "invalid native object; delete() likely already called"); + return ; + } + (arg1)->wrappedFunction(...); +</pre> +</div> + +<p> +Note that if you have a parameter named <tt>self</tt> then it +will also match the typemap. One work around is to create an interface file that wraps +the method, but give the argument a name other than <tt>self</tt>. +</p> + +<H2><a name="Typemaps_nn51"></a>10.16 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. +There you may also find more hands-on practical examples. +</p> + +</body> +</html> |
