The great merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6fcc22a1f8
commit
516036631c
1508 changed files with 125983 additions and 44037 deletions
427
SWIG/Doc/Manual/Arguments.html
Normal file
427
SWIG/Doc/Manual/Arguments.html
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Argument Handling</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
<a name="n1"></a><H1>7 Argument Handling</H1>
|
||||
<!-- INDEX -->
|
||||
<ul>
|
||||
<li><a href="#n2">The typemaps.i library</a>
|
||||
<ul>
|
||||
<li><a href="#n3">Introduction</a>
|
||||
<li><a href="#n4">Input parameters</a>
|
||||
<li><a href="#n5">Output parameters</a>
|
||||
<li><a href="#n6">Input/Output parameters</a>
|
||||
<li><a href="#n7">Using different names</a>
|
||||
</ul>
|
||||
<li><a href="#n8">Applying constraints to input values</a>
|
||||
<ul>
|
||||
<li><a href="#n9">Simple constraint example</a>
|
||||
<li><a href="#n10">Constraint methods</a>
|
||||
<li><a href="#n11">Applying constraints to new datatypes</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<!-- 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.
|
||||
|
||||
<a name="n2"></a><H2>7.1 The typemaps.i library</H2>
|
||||
|
||||
|
||||
This section describes the <tt>typemaps.i</tt> library file--commonly used to
|
||||
change certain properties of argument conversion.
|
||||
|
||||
<a name="n3"></a><H3>7.1.1 Introduction</H3>
|
||||
|
||||
|
||||
Suppose you had a C function like this:
|
||||
|
||||
<p>
|
||||
<blockquote><pre>void add(double a, double b, double *result) {
|
||||
*result = a + b;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<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>
|
||||
One way to deal with this is to use the
|
||||
<tt>typemaps.i</tt> library file and write interface code like this:
|
||||
|
||||
<p>
|
||||
<blockquote><pre>// Simple example using typemaps
|
||||
%module example
|
||||
%include "typemaps.i"
|
||||
|
||||
%apply double *OUTPUT { double *result };
|
||||
extern void add(double a, double b, double *result);
|
||||
</pre></blockquote>
|
||||
|
||||
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>
|
||||
<blockquote><pre>
|
||||
>>> a = add(3,4)
|
||||
>>> print a
|
||||
7
|
||||
>>>
|
||||
</pre></blockquote>
|
||||
|
||||
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>
|
||||
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>
|
||||
<blockquote><pre>
|
||||
%module example
|
||||
%include "typemaps.i"
|
||||
|
||||
%apply double *OUTPUT { double *result };
|
||||
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></blockquote>
|
||||
|
||||
In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow.
|
||||
|
||||
<p>
|
||||
Typemap transformations can even be extended to multiple return values.
|
||||
For example, consider this code:
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
||||
In this case, the function returns multiple values, allowing it to be used like this:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> w,h = genwinsize(wid)
|
||||
>>> print w
|
||||
400
|
||||
>>> print h
|
||||
300
|
||||
>>>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<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:
|
||||
|
||||
<blockquote><pre>// Simple example using typemaps
|
||||
%module example
|
||||
%include "typemaps.i"
|
||||
|
||||
extern void add(double a, double b, double *OUTPUT);
|
||||
</pre></blockquote>
|
||||
|
||||
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:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
%clear double *result; // Remove all typemaps for double *result
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<a name="n4"></a><H3>7.1.2 Input parameters</H3>
|
||||
|
||||
|
||||
<p>
|
||||
The following typemaps instruct SWIG that a pointer really only holds a single
|
||||
input value:
|
||||
|
||||
<blockquote><pre>
|
||||
int *INPUT
|
||||
short *INPUT
|
||||
long *INPUT
|
||||
unsigned int *INPUT
|
||||
unsigned short *INPUT
|
||||
unsigned long *INPUT
|
||||
double *INPUT
|
||||
float *INPUT
|
||||
</pre></blockquote>
|
||||
|
||||
When used, it allows values to be passed instead of pointers. For example, consider this
|
||||
function:
|
||||
|
||||
<blockquote><pre>
|
||||
double add(double *a, double *b) {
|
||||
return *a+*b;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
Now, consider this SWIG interface:
|
||||
|
||||
<p>
|
||||
<blockquote><pre>%module example
|
||||
%include "typemaps.i"
|
||||
...
|
||||
extern double add(double *INPUT, double *INPUT);
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
When the function is used in the scripting language interpreter, it will work like this:
|
||||
<p>
|
||||
<blockquote><pre>
|
||||
result = add(3,4)
|
||||
</pre></blockquote>
|
||||
|
||||
<a name="n5"></a><H3>7.1.3 Output parameters</H3>
|
||||
|
||||
|
||||
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>
|
||||
<blockquote><pre>int *OUTPUT
|
||||
short *OUTPUT
|
||||
long *OUTPUT
|
||||
unsigned int *OUTPUT
|
||||
unsigned short *OUTPUT
|
||||
unsigned long *OUTPUT
|
||||
double *OUTPUT
|
||||
float *OUTPUT
|
||||
|
||||
</pre></blockquote>
|
||||
These methods can be used as shown in an earlier example. For example, if you have this C function :<p>
|
||||
<p>
|
||||
<blockquote><pre>void add(double a, double b, double *c) {
|
||||
*c = a+b;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
A SWIG interface file might look like this :<p>
|
||||
|
||||
<p>
|
||||
<blockquote><pre>%module example
|
||||
%include "typemaps.i"
|
||||
...
|
||||
extern void add(double a, double b, double *OUTPUT);
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
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>
|
||||
If the function also returns a value, it is returned along with the argument. For example,
|
||||
if you had this:
|
||||
|
||||
<blockquote><pre>
|
||||
extern int foo(double a, double b, double *OUTPUT);
|
||||
</pre></blockquote>
|
||||
|
||||
The function will return two values like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
iresult, dresult = foo(3.5, 2)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<a name="n6"></a><H3>7.1.4 Input/Output parameters</H3>
|
||||
|
||||
|
||||
When a pointer serves as both an input and output value you can use
|
||||
the following typemaps :<p>
|
||||
|
||||
<blockquote><pre>
|
||||
int *INOUT
|
||||
short *INOUT
|
||||
long *INOUT
|
||||
unsigned int *INOUT
|
||||
unsigned short *INOUT
|
||||
unsigned long *INOUT
|
||||
double *INOUT
|
||||
float *INOUT
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
A C function that uses this might be something like this:<p>
|
||||
|
||||
<p>
|
||||
<blockquote><pre>void negate(double *x) {
|
||||
*x = -(*x);
|
||||
}
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
To make x function as both and input and output value, declare the
|
||||
function like this in an interface file :<p>
|
||||
|
||||
<p>
|
||||
<blockquote><pre>%module example
|
||||
%include typemaps.i
|
||||
...
|
||||
extern void negate(double *INOUT);
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
Now within a script, you can simply call the function normally :<p>
|
||||
|
||||
<p>
|
||||
<blockquote><pre>a = negate(3); # a = -3 after calling this
|
||||
</pre></blockquote>
|
||||
|
||||
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>
|
||||
<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.
|
||||
|
||||
<a name="n7"></a><H3>7.1.5 Using different names</H3>
|
||||
|
||||
|
||||
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>
|
||||
<blockquote><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></blockquote>
|
||||
|
||||
To clear a rule, the <tt>%clear</tt> directive is used:
|
||||
|
||||
<p>
|
||||
<blockquote><pre>%clear double *result;
|
||||
%clear Int32 *in, long *x;
|
||||
</pre></blockquote>
|
||||
|
||||
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.
|
||||
|
||||
<a name="n8"></a><H2>7.2 Applying constraints to input values</H2>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
<a name="n9"></a><H3>7.2.1 Simple constraint example</H3>
|
||||
|
||||
|
||||
The constraints library is best illustrated by the following interface
|
||||
file :<p>
|
||||
<p>
|
||||
|
||||
<blockquote><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></blockquote>
|
||||
|
||||
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>
|
||||
|
||||
<a name="n10"></a><H3>7.2.2 Constraint methods</H3>
|
||||
|
||||
|
||||
The following constraints are currently available<p>
|
||||
|
||||
<blockquote><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></blockquote>
|
||||
|
||||
<a name="n11"></a><H3>7.2.3 Applying constraints to new datatypes</H3>
|
||||
|
||||
|
||||
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>
|
||||
<p>
|
||||
|
||||
<blockquote><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></blockquote>
|
||||
|
||||
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>
|
||||
|
||||
<p>
|
||||
<blockquote><pre>%clear Real in;
|
||||
%clear Vector *;
|
||||
</pre></blockquote>
|
||||
|
||||
<p><hr>
|
||||
|
||||
<address>SWIG 1.3 - Last Modified : October 13, 2002</address>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue