/tags/rel-1-3-27/SWIG/Doc/Manual/Arguments.html
HTML | 498 lines | 387 code | 109 blank | 2 comment | 0 complexity | 84750f1c7a58b50ac42419d1c0624990 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>Argument Handling</title>
- <link rel="stylesheet" type="text/css" href="style.css">
- </head>
- <body bgcolor="#ffffff">
- <H1><a name="Arguments"></a>9 Argument Handling</H1>
- <!-- INDEX -->
- <div class="sectiontoc">
- <ul>
- <li><a href="#Arguments_nn2">The typemaps.i library</a>
- <ul>
- <li><a href="#Arguments_nn3">Introduction</a>
- <li><a href="#Arguments_nn4">Input parameters</a>
- <li><a href="#Arguments_nn5">Output parameters</a>
- <li><a href="#Arguments_nn6">Input/Output parameters</a>
- <li><a href="#Arguments_nn7">Using different names</a>
- </ul>
- <li><a href="#Arguments_nn8">Applying constraints to input values</a>
- <ul>
- <li><a href="#Arguments_nn9">Simple constraint example</a>
- <li><a href="#Arguments_nn10">Constraint methods</a>
- <li><a href="#Arguments_nn11">Applying constraints to new datatypes</a>
- </ul>
- </ul>
- </div>
- <!-- INDEX -->
- <b>Disclaimer: This chapter is under construction.</b>
- <p>
- In Chapter 3, SWIG's treatment of basic datatypes and pointers was
- described. In particular, primitive types such as <tt>int</tt> and
- <tt>double</tt> are mapped to corresponding types in the target
- language. For everything else, pointers are used to refer to
- structures, classes, arrays, and other user-defined datatypes.
- However, in certain applications it is desirable to change SWIG's
- handling of a specific datatype. For example, you might want to
- return multiple values through the arguments of a function. This chapter
- describes some of the techniques for doing this.
- </p>
- <H2><a name="Arguments_nn2"></a>9.1 The typemaps.i library</H2>
- <p>
- This section describes the <tt>typemaps.i</tt> library file--commonly used to
- change certain properties of argument conversion.
- </p>
- <H3><a name="Arguments_nn3"></a>9.1.1 Introduction</H3>
- <p>
- Suppose you had a C function like this:
- </p>
- <div class="code"><pre>
- void add(double a, double b, double *result) {
- *result = a + b;
- }
- </pre></div>
- <p>
- From reading the source code, it is clear that the function is storing
- a value in the <tt>double *result</tt> parameter. However, since SWIG
- does not examine function bodies, it has no way to know that this is
- the underlying behavior.
- </p>
- <p>
- One way to deal with this is to use the
- <tt>typemaps.i</tt> library file and write interface code like this:
- </p>
- <div class="code"><pre>
- // Simple example using typemaps
- %module example
- %include "typemaps.i"
- %apply double *OUTPUT { double *result };
- %inlne %{
- extern void add(double a, double b, double *result);
- %}
- </pre></div>
- <p>
- The <tt>%apply</tt> directive tells SWIG that you are going to apply
- a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the
- name of a rule that defines how to return an output value from an argument of type
- <tt>double *</tt>. This rule gets applied to all of the datatypes
- listed in curly braces-- in this case "<tt>double *result</tt>".</p>
- <p>
- When the resulting module is created, you can now use the function
- like this (shown for Python):
- </p>
- <div class="targetlang"><pre>
- >>> a = add(3,4)
- >>> print a
- 7
- >>>
- </pre></div>
- <p>
- In this case, you can see how the output value normally returned in
- the third argument has magically been transformed into a function
- return value. Clearly this makes the function much easier to use
- since it is no longer necessary to manufacture a special <tt>double
- *</tt> object and pass it to the function somehow.
- </p>
- <p>
- Once a typemap has been applied to a type, it stays in effect for all future occurrences
- of the type and name. For example, you could write the following:
- </p>
- <div class="code"><pre>
- %module example
- %include "typemaps.i"
- %apply double *OUTPUT { double *result };
- %inline %{
- extern void add(double a, double b, double *result);
- extern void sub(double a, double b, double *result);
- extern void mul(double a, double b, double *result);
- extern void div(double a, double b, double *result);
- %}
- ...
- </pre></div>
- <p>
- In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow.
- </p>
- <p>
- Typemap transformations can even be extended to multiple return values.
- For example, consider this code:
- </p>
- <div class="code">
- <pre>
- %include "typemaps.i"
- %apply int *OUTPUT { int *width, int *height };
- // Returns a pair (width,height)
- void getwinsize(int winid, int *width, int *height);
- </pre>
- </div>
- <p>
- In this case, the function returns multiple values, allowing it to be used like this:
- </p>
- <div class="targetlang"><pre>
- >>> w,h = genwinsize(wid)
- >>> print w
- 400
- >>> print h
- 300
- >>>
- </pre>
- </div>
- <p>
- It should also be noted that although the <tt>%apply</tt> directive is
- used to associate typemap rules to datatypes, you can also use the
- rule names directly in arguments. For example, you could write this:
- </p>
- <div class="code"><pre>
- // Simple example using typemaps
- %module example
- %include "typemaps.i"
- %{
- extern void add(double a, double b, double *OUTPUT);
- %}
- extern void add(double a, double b, double *OUTPUT);
- </pre></div>
- <p>
- Typemaps stay in effect until they are explicitly deleted or redefined to something
- else. To clear a typemap, the <tt>%clear</tt> directive should be used. For example:
- </p>
- <div class="code">
- <pre>
- %clear double *result; // Remove all typemaps for double *result
- </pre>
- </div>
- <H3><a name="Arguments_nn4"></a>9.1.2 Input parameters</H3>
- <p>
- The following typemaps instruct SWIG that a pointer really only holds a single
- input value:
- </p>
- <div class="code"><pre>
- int *INPUT
- short *INPUT
- long *INPUT
- unsigned int *INPUT
- unsigned short *INPUT
- unsigned long *INPUT
- double *INPUT
- float *INPUT
- </pre></div>
- <p>
- When used, it allows values to be passed instead of pointers. For example, consider this
- function:
- </p>
- <div class="code"><pre>
- double add(double *a, double *b) {
- return *a+*b;
- }
- </pre></div>
- <p>
- Now, consider this SWIG interface:
- </p>
- <div class="code"><pre>
- %module example
- %include "typemaps.i"
- ...
- %{
- extern double add(double *, double *);
- %}
- extern double add(double *INPUT, double *INPUT);
- </pre></div>
- <p>
- When the function is used in the scripting language interpreter, it will work like this:
- </p>
- <div class="targetlang"><pre>
- result = add(3,4)
- </pre></div>
- <H3><a name="Arguments_nn5"></a>9.1.3 Output parameters</H3>
- <p>
- The following typemap rules tell SWIG that pointer is the output value of a
- function. When used, you do not need to supply the argument when
- calling the function. Instead, one or more output values are returned.
- </p>
- <div class="code"><pre>
- int *OUTPUT
- short *OUTPUT
- long *OUTPUT
- unsigned int *OUTPUT
- unsigned short *OUTPUT
- unsigned long *OUTPUT
- double *OUTPUT
- float *OUTPUT
- </pre></div>
- <p>
- These methods can be used as shown in an earlier example. For example, if you have this C function :</p>
- <div class="code"><pre>
- void add(double a, double b, double *c) {
- *c = a+b;
- }
- </pre></div>
- <p>
- A SWIG interface file might look like this :</p>
- <div class="code"><pre>
- %module example
- %include "typemaps.i"
- ...
- %inline %{
- extern void add(double a, double b, double *OUTPUT);
- %}
- </pre></div>
- <p>
- In this case, only a single output value is returned, but this is not
- a restriction. An arbitrary number of output values can be returned by applying
- the output rules to more than one argument (as shown previously).
- </p>
- <p>
- If the function also returns a value, it is returned along with the argument. For example,
- if you had this:
- </p>
- <div class="code"><pre>
- extern int foo(double a, double b, double *OUTPUT);
- </pre></div>
- <p>
- The function will return two values like this:
- </p>
- <div class="targetlang">
- <pre>
- iresult, dresult = foo(3.5, 2)
- </pre>
- </div>
- <H3><a name="Arguments_nn6"></a>9.1.4 Input/Output parameters</H3>
- <p>
- When a pointer serves as both an input and output value you can use
- the following typemaps :</p>
- <div class="code"><pre>
- int *INOUT
- short *INOUT
- long *INOUT
- unsigned int *INOUT
- unsigned short *INOUT
- unsigned long *INOUT
- double *INOUT
- float *INOUT
- </pre></div>
- <p>
- A C function that uses this might be something like this:</p>
- <div class="code"><pre>
- void negate(double *x) {
- *x = -(*x);
- }
- </pre></div>
- <p>
- To make x function as both and input and output value, declare the
- function like this in an interface file :</p>
- <div class="code"><pre>
- %module example
- %include typemaps.i
- ...
- %{
- extern void negate(double *);
- %}
- extern void negate(double *INOUT);
- </pre></div>
- <p>
- Now within a script, you can simply call the function normally :</p>
- <div class="targetlang"><pre>
- a = negate(3); # a = -3 after calling this
- </pre></div>
- <p>
- One subtle point of the <tt>INOUT</tt> rule is that many scripting languages
- enforce mutability constraints on primitive objects (meaning that simple objects
- like integers and strings aren't supposed to change). Because of this, you can't
- just modify the object's value in place as the underlying C function does in this example.
- Therefore, the <tt>INOUT</tt> rule returns the modified value as a new object
- rather than directly overwriting the value of the original input object.
- </p>
- <p>
- <b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
- SWIG. Backwards compatibility is preserved, but deprecated.
- </p>
- <H3><a name="Arguments_nn7"></a>9.1.5 Using different names</H3>
- <p>
- As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
- <tt>INOUT</tt> typemaps to different argument names. For example:
- </p>
- <div class="code"><pre>
- // Make double *result an output value
- %apply double *OUTPUT { double *result };
- // Make Int32 *in an input value
- %apply int *INPUT { Int32 *in };
- // Make long *x inout
- %apply long *INOUT {long *x};
- </pre></div>
- <p>
- To clear a rule, the <tt>%clear</tt> directive is used:
- </p>
- <div class="code"><pre>
- %clear double *result;
- %clear Int32 *in, long *x;
- </pre></div>
- <p>
- Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the
- file or a matching <tt>%clear</tt> declaration.
- </p>
- <H2><a name="Arguments_nn8"></a>9.2 Applying constraints to input values</H2>
- <p>
- In addition to changing the handling of various input values, it is
- also possible to use typemaps to apply constraints. For example, maybe you want to
- insure that a value is positive, or that a pointer is non-NULL. This
- can be accomplished including the <tt>constraints.i</tt> library file.
- </p>
- <H3><a name="Arguments_nn9"></a>9.2.1 Simple constraint example</H3>
- <p>
- The constraints library is best illustrated by the following interface
- file :</p>
- <div class="code"><pre>
- // Interface file with constraints
- %module example
- %include "constraints.i"
- double exp(double x);
- double log(double POSITIVE); // Allow only positive values
- double sqrt(double NONNEGATIVE); // Non-negative values only
- double inv(double NONZERO); // Non-zero values
- void free(void *NONNULL); // Non-NULL pointers only
- </pre></div>
- <p>
- The behavior of this file is exactly as you would expect. If any of
- the arguments violate the constraint condition, a scripting language
- exception will be raised. As a result, it is possible to catch bad
- values, prevent mysterious program crashes and so on.</p>
- <H3><a name="Arguments_nn10"></a>9.2.2 Constraint methods</H3>
- <p>
- The following constraints are currently available</p>
- <div class="code"><pre>
- POSITIVE Any number > 0 (not zero)
- NEGATIVE Any number < 0 (not zero)
- NONNEGATIVE Any number >= 0
- NONPOSITIVE Any number <= 0
- NONZERO Nonzero number
- NONNULL Non-NULL pointer (pointers only).
- </pre></div>
- <H3><a name="Arguments_nn11"></a>9.2.3 Applying constraints to new datatypes</H3>
- <p>
- The constraints library only supports the primitive C datatypes, but it
- is easy to apply it to new datatypes using <tt>%apply</tt>. For
- example :</p>
- <div class="code"><pre>
- // Apply a constraint to a Real variable
- %apply Number POSITIVE { Real in };
- // Apply a constraint to a pointer type
- %apply Pointer NONNULL { Vector * };
- </pre></div>
- <p>
- The special types of "Number" and "Pointer" can be applied to any
- numeric and pointer variable type respectively. To later remove a
- constraint, the <tt>%clear</tt> directive can be used :</p>
- <div class="code"><pre>
- %clear Real in;
- %clear Vector *;
- </pre></div>
- </body>
- </html>