Update typemaps chapter and document new default typemap matching rules

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11983 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2010-04-09 21:41:09 +00:00
commit 00b1468091

View file

@ -580,14 +580,14 @@ suppose you had a declaration like this,
<div class="code">
<pre>
Foo *make_Foo();
Foo *make_Foo(int n);
</pre>
</div>
<p>
and you wanted to tell SWIG that <tt>make_Foo()</tt> returned a newly
and you wanted to tell SWIG that <tt>make_Foo(int n)</tt> returned a newly
allocated object (for the purposes of providing better memory
management). Clearly, this property of <tt>make_Foo()</tt> is
management). Clearly, this property of <tt>make_Foo(int n)</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
@ -991,7 +991,7 @@ types (<tt>std::string</tt> and <tt>Foo::string</tt>).
<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>.
within a particular namespace. In this example, this is done using the forward class declaration <tt>class string</tt>.
</p>
<H2><a name="Typemaps_pattern_matching"></a>10.3 Pattern matching rules</H2>
@ -1085,16 +1085,16 @@ shows how some of the basic rules are applied:
... 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)
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); // const int *z 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_typedef_reductions"></a>10.3.2 Typedef reductions</H3>
<H3><a name="Typemaps_typedef_reductions"></a>10.3.2 Typedef reductions matching</H3>
<p>
@ -1269,58 +1269,77 @@ void go(Struct aStruct);
</pre>
</div>
<H3><a name="Typemaps_nn19"></a>10.3.3 Default typemaps</H3>
<H3><a name="Typemaps_nn19"></a>10.3.3 Default typemap matching rules</H3>
<p>
If the basic pattern matching rules result in no match being made, even after typedef reductions,
the default typemap matching rules are used to look for a suitable typemap match.
These rules match a generic typemap based on the reserved <tt>SWIGTYPE</tt> base type.
For example pointers will use <tt>SWIGTYPE *</tt> and references will use <tt>SWIGTYPE &amp;</tt>.
More precisely, the rules are based on the C++ template partial specialization matching rules used
by C++ compilers when looking for an appropriate partial template specialization.
This means that a match is chosen from the most specialized set of generic typemap types available. For example,
when looking for a match to <tt>int const *</tt>, the rules will prefer to match <tt>SWIGTYPE const *</tt>
if available before matching <tt>SWIGTYPE *</tt>, before matching <tt>SWIGTYPE</tt>.
</p>
<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:
is entirely straightforward. For example, a set of typemaps for primitives marshalled by value or
const reference 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";
%typemap(in) int "... convert to int ...";
%typemap(in) short "... convert to short ...";
%typemap(in) float "... convert to float ...";
...
%typemap(in) const int &amp; "... convert ...";
%typemap(in) const short &amp; "... convert ...";
%typemap(in) const float &amp; "... convert ...";
...
</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.
mapped to a primitive type by value or const reference through <tt>typedef</tt> will be picked
up by one of these primitive typemaps.
Most language modules also define typemaps for char pointers and char arrays to handle strings,
so these non-default types will also be used in preference as the basic typemap matching rules
provide a better match than the default typemap matching rules.
</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:
Below is a list of the typical default types supplied by language modules, showing what the "in" typemap would look like:
</p>
<div class="code">
<pre>
%typemap(in) SWIGTYPE * { ... default pointer handling ... }
%typemap(in) SWIGTYPE &amp; { ... 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 ... }
%typemap(in) SWIGTYPE &amp; { ... default reference handling ... };
%typemap(in) SWIGTYPE * { ... default pointer handling ... };
%typemap(in) SWIGTYPE *const { ... default pointer const handling ... };
%typemap(in) SWIGTYPE *const&amp; { ... default pointer const reference handling ... };
%typemap(in) SWIGTYPE[ANY] { ... 1D fixed size arrays handlling ... };
%typemap(in) SWIGTYPE [] { ... unknown sized array handling ... };
%typemap(in) enum SWIGTYPE { ... default handling for enum values ... };
%typemap(in) const enum SWIGTYPE &amp; { ... default handling for const enum reference values ... };
%typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... };
%typemap(in) SWIGTYPE { ... simple default 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:
If you wanted to change SWIG's default handling for
simple pointers, you would simply redefine the rule for <tt>SWIGTYPE *</tt>.
Note, the simple default 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 ... }
%typemap(in) SWIGTYPE { ... simple default handling ... }
</pre>
</div>
@ -1339,7 +1358,7 @@ double dot_product(Vector a, Vector b);
<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).
to convert the value into pointers (<a href="SWIG.html#SWIG_nn22">as described in this earlier section</a>).
</p>
<p>
@ -1351,34 +1370,7 @@ 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 &amp; { ... enum references ... }
%typemap(in) const enum SWIGTYPE &amp; { ... const enum references ... }
%typemap(in) SWIGTYPE *&amp; { ... pointers passed by reference ... }
%typemap(in) SWIGTYPE * const &amp; { ... 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:
Let's consider an example where the following typemaps are defined and SWIG is looking for the best match for the enum shown below:
</p>
<div class="code">
@ -1397,12 +1389,22 @@ const Hello &amp;hi;
<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.
The best way to explore the default typemaps is to look at the ones
already defined for a particular language module. Typemap
definitions are usually found in the SWIG library in a file such as
<tt>java.swg</tt>, <tt>csharp.swg</tt> etc.
However, for many of the target languages the typemaps are hidden behind complicated macros,
so the best way to view the default typemaps, or any typemaps for that matter,
is to look at the preprocessed output by running <tt>swig -E</tt> on any interface file.
Finally the best way to view the typemap matching rules in action is via the <a href="#Typemaps_debugging_search">debugging typemap pattern matching</a> options covered later on.
</p>
<p>
<b>Compatibility note: </b> The default typemap matching rules were modified in SWIG-2.0.0 from a slightly
simpler scheme to match the current C++ template partial specialization matching rules.
</p>
@ -1501,9 +1503,17 @@ example.h:3: Searching for a suitable 'in' typemap for: Row4 rows[10]
<p>
showing that the best default match supplied by SWIG is the <tt>SWIGTYPE []</tt> typemap.
As the example shows, the successful match displays just the typemap method name and type in this format: <tt>%typemap(method) type</tt>.
As the example shows, the successful match displays the used typemap source including typemap method, type and optional name in one of these simplified formats: <p>
<ul>
<li> <tt>Using: %typemap(method) type name</tt>
<li> <tt>Using: %typemap(method) type name = type2 name2</tt>
<li> <tt>Using: %apply type2 name2 { type name }</tt>
</ul>
<p>
This information might meet your debugging needs, however, you might want to analyze further.
If you next invoke SWIG with the <tt>-E</tt> option to display the preprocessed output, and search for this particular typemap,
If you next invoke SWIG with the <tt>-E</tt> option to display the preprocessed output, and search for the particular typemap used,
you'll find the full typemap contents (example shown below for Python):
</p>
@ -1543,7 +1553,7 @@ SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
<p>
Searches for multi-argument typemaps are not mentioned unless a matching multi-argument typemap does actually exist.
For example, the output for the code in the <a href="#Typemaps_multi_argument_typemaps_patterns">previous section</a> is as follows:
For example, the output for the code in the <a href="#Typemaps_multi_argument_typemaps_patterns">earlier multi-arguments section</a> is as follows:
</p>
<div class="shell">
@ -1560,7 +1570,7 @@ example.h:39: Searching for a suitable 'in' typemap for: char *buffer
<p>
The second option for debugging is <tt>-debug-tmused</tt> and this displays the typemaps used.
This option is a less verbose version of the <tt>-debug-tmsearch</tt> option as it only displays each successfully found typemap on a separate single line.
The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used.
The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used in the same simplified format output by the <tt>-debug-tmsearch</tt> option.
Below is the output for the example code at the start of this section on debugging.
</p>
@ -1711,12 +1721,16 @@ Occasionally, typemap code will be specified using a few alternative forms. For
%typemap(in) int %{
$1 = PyInt_AsLong($input);
%}
%typemap(in, noblock=1) int {
$1 = PyInt_AsLong($input);
}
</pre>
</div>
<p>
These two forms are mainly used for cosmetics--the specified code is not enclosed inside
These three 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.
Note that only the third of the three typemaps have the typemap code passed through the SWIG preprocessor.
</p>
<H3><a name="Typemaps_nn23"></a>10.4.2 Declaring new local variables</H3>
@ -1845,7 +1859,7 @@ wrap_foo() {
<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.
apply). At this time, only typemaps that apply to argument conversion support this (input typemaps such as the "in" typemap).
</p>
<p>
@ -2262,7 +2276,7 @@ When <tt>numinputs</tt> is set to 0, the argument is effectively ignored and can
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.
<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 multiple adjacent C/C++ arguments.
</p>
<p>
@ -2293,7 +2307,7 @@ the input argument is the correct type.
<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."
"typecheck" typemaps. More details about this follow in the <a href="#Typemaps_overloading">Typemaps and overloading</a> section.
</p>
<H3><a name="Typemaps_nn28"></a>10.5.3 "out" typemap</H3>
@ -2441,7 +2455,7 @@ return values are often appended to return value of the function.
</p>
<p>
See the <tt>typemaps.i</tt> library for examples.
See the <tt>typemaps.i</tt> library file for examples.
</p>
<H3><a name="Typemaps_nn33"></a>10.5.8 "freearg" typemap</H3>
@ -2766,9 +2780,8 @@ 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.
$ swig -python example.i
example.i:10: Warning 462: Unable to set variable of type float [4].
</pre></div>
<p>
@ -2865,7 +2878,7 @@ useless and has since been eliminated. To return structure members, simply use
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>
checking the values of function arguments. For example:</p>
<div class="code"><pre>
%module math
@ -2888,7 +2901,7 @@ your program terminated with an error message.</p>
<p>
This kind of checking can be particularly useful when working with
pointers. For example :</p>
pointers. For example:</p>
<div class="code"><pre>
%typemap(check) Vector * {
@ -2906,10 +2919,6 @@ 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 target languages</H2>
@ -2986,7 +2995,7 @@ struct XX {
</div>
<p>
The "out" typemap shown is the default typemap for C# when returning by objects by value.
The "out" typemap shown is the default typemap for C# when returning objects by value.
When making a call to <tt>XX::create()</tt> from C#, the output is as follows:
</p>
@ -3108,7 +3117,7 @@ try {
</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.
It should be clear that the above code cannot be used as the argument to the copy constructor call, that is, for the <tt>$1</tt> substitution.
</p>
<p>
@ -3159,14 +3168,14 @@ list of strings like this:
<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.
typemaps, this type of conversion is possible, but extremely painful.
Multi-argument typemaps help in this situation.
</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
convert a <em>single</em> object in the target language to a set of
consecutive function arguments in C/C++. For example, the following multi-argument
maps perform the conversion described for the above example:
</p>
@ -3390,7 +3399,9 @@ this, you could write a multi-argument typemap like this:
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).
ordering (and perform conversions if needed). Note that multi-argument typemaps cannot deal
with non-consecutive C/C++ arguments; a workaround such as a helper function re-ordering
the arguments to make them consecutive will need to be written.
</p>
<H2><a name="runtime_type_checker"></a>10.10 The run-time type checker</H2>
@ -3693,7 +3704,7 @@ interface file.
<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
<tt>Lib/swigrun.swg</tt> in the SWIG library contains all of the source of the generated 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.
@ -3703,7 +3714,9 @@ managed.
<p>
In many target languages, SWIG fully supports C++ overloaded methods and functions. For example,
This section does not apply to the statically typed languages like Java and C#, where overloading
of the types is handled much like C++ by generating overloaded methods in the target language.
In many of the other target languages, SWIG still fully supports C++ overloaded methods and functions. For example,
if you have a collection of functions like this:
</p>
@ -4215,7 +4228,7 @@ sure that the typemaps sharing information have exactly the same types and names
<p>
All the rules discussed for Typemaps apply to C++ as well as C.
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
@ -4235,7 +4248,8 @@ For example, if wrapping for Java generation:
<pre>
%typemap(check) SWIGTYPE *self %{
if (!$1) {
SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "swigCPtr null");
SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException,
"invalid native object; delete() likely already called");
return $null;
}
%}
@ -4260,14 +4274,14 @@ The generated code will look something like:
"invalid native object; delete() likely already called");
return ;
}
(arg1)->wrappedFunction(...);
(arg1)-&gt;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>.
the method, but gives 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>