mirror of https://github.com/swig/swig
493 lines
12 KiB
HTML
493 lines
12 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Argument Handling</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Arguments">13 Argument Handling</a></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 -->
|
|
|
|
|
|
|
|
<p>
|
|
In Chapter 5, 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">13.1 The typemaps.i library</a></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">13.1.1 Introduction</a></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 };
|
|
%inline %{
|
|
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">13.1.2 Input parameters</a></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">13.1.3 Output parameters</a></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">13.1.4 Input/Output parameters</a></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>
|
|
|
|
<H3><a name="Arguments_nn7">13.1.5 Using different names</a></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">13.2 Applying constraints to input values</a></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">13.2.1 Simple constraint example</a></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
|
|
int fclose(FILE *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">13.2.2 Constraint methods</a></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">13.2.3 Applying constraints to new datatypes</a></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>
|