Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v9 / html / swig / Arguments.html
CommitLineData
920dae64
AT
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3<head>
4<title>Argument Handling</title>
5<link rel="stylesheet" type="text/css" href="style.css">
6</head>
7
8<body bgcolor="#ffffff">
9<H1><a name="Arguments"></a>9 Argument Handling</H1>
10<!-- INDEX -->
11<div class="sectiontoc">
12<ul>
13<li><a href="#Arguments_nn2">The typemaps.i library</a>
14<ul>
15<li><a href="#Arguments_nn3">Introduction</a>
16<li><a href="#Arguments_nn4">Input parameters</a>
17<li><a href="#Arguments_nn5">Output parameters</a>
18<li><a href="#Arguments_nn6">Input/Output parameters</a>
19<li><a href="#Arguments_nn7">Using different names</a>
20</ul>
21<li><a href="#Arguments_nn8">Applying constraints to input values</a>
22<ul>
23<li><a href="#Arguments_nn9">Simple constraint example</a>
24<li><a href="#Arguments_nn10">Constraint methods</a>
25<li><a href="#Arguments_nn11">Applying constraints to new datatypes</a>
26</ul>
27</ul>
28</div>
29<!-- INDEX -->
30
31
32
33<b>Disclaimer: This chapter is under construction.</b>
34
35<p>
36In Chapter 3, SWIG's treatment of basic datatypes and pointers was
37described. In particular, primitive types such as <tt>int</tt> and
38<tt>double</tt> are mapped to corresponding types in the target
39language. For everything else, pointers are used to refer to
40structures, classes, arrays, and other user-defined datatypes.
41However, in certain applications it is desirable to change SWIG's
42handling of a specific datatype. For example, you might want to
43return multiple values through the arguments of a function. This chapter
44describes some of the techniques for doing this.
45</p>
46
47<H2><a name="Arguments_nn2"></a>9.1 The typemaps.i library</H2>
48
49
50<p>
51This section describes the <tt>typemaps.i</tt> library file--commonly used to
52change certain properties of argument conversion.
53</p>
54
55<H3><a name="Arguments_nn3"></a>9.1.1 Introduction</H3>
56
57
58<p>
59Suppose you had a C function like this:
60</p>
61
62<div class="code"><pre>
63void add(double a, double b, double *result) {
64 *result = a + b;
65}
66</pre></div>
67
68<p>
69From reading the source code, it is clear that the function is storing
70a value in the <tt>double *result</tt> parameter. However, since SWIG
71does not examine function bodies, it has no way to know that this is
72the underlying behavior.
73</p>
74
75<p>
76One way to deal with this is to use the
77<tt>typemaps.i</tt> library file and write interface code like this:
78</p>
79
80<div class="code"><pre>
81// Simple example using typemaps
82%module example
83%include "typemaps.i"
84
85%apply double *OUTPUT { double *result };
86%inlne %{
87extern void add(double a, double b, double *result);
88%}
89</pre></div>
90
91<p>
92The <tt>%apply</tt> directive tells SWIG that you are going to apply
93a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the
94name of a rule that defines how to return an output value from an argument of type
95<tt>double *</tt>. This rule gets applied to all of the datatypes
96listed in curly braces-- in this case "<tt>double *result</tt>".</p>
97
98<p>
99When the resulting module is created, you can now use the function
100like this (shown for Python):
101</p>
102
103<div class="targetlang"><pre>
104&gt;&gt;&gt; a = add(3,4)
105&gt;&gt;&gt; print a
1067
107&gt;&gt;&gt;
108</pre></div>
109
110<p>
111In this case, you can see how the output value normally returned in
112the third argument has magically been transformed into a function
113return value. Clearly this makes the function much easier to use
114since it is no longer necessary to manufacture a special <tt>double
115*</tt> object and pass it to the function somehow.
116</p>
117
118<p>
119Once a typemap has been applied to a type, it stays in effect for all future occurrences
120of the type and name. For example, you could write the following:
121</p>
122
123<div class="code"><pre>
124%module example
125%include "typemaps.i"
126
127%apply double *OUTPUT { double *result };
128
129%inline %{
130extern void add(double a, double b, double *result);
131extern void sub(double a, double b, double *result);
132extern void mul(double a, double b, double *result);
133extern void div(double a, double b, double *result);
134%}
135...
136</pre></div>
137
138<p>
139In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow.
140</p>
141
142<p>
143Typemap transformations can even be extended to multiple return values.
144For example, consider this code:
145</p>
146
147<div class="code">
148<pre>
149%include "typemaps.i"
150%apply int *OUTPUT { int *width, int *height };
151
152// Returns a pair (width,height)
153void getwinsize(int winid, int *width, int *height);
154</pre>
155</div>
156
157<p>
158In this case, the function returns multiple values, allowing it to be used like this:
159</p>
160
161<div class="targetlang"><pre>
162&gt;&gt;&gt; w,h = genwinsize(wid)
163&gt;&gt;&gt; print w
164400
165&gt;&gt;&gt; print h
166300
167&gt;&gt;&gt;
168</pre>
169</div>
170
171<p>
172It should also be noted that although the <tt>%apply</tt> directive is
173used to associate typemap rules to datatypes, you can also use the
174rule names directly in arguments. For example, you could write this:
175</p>
176
177<div class="code"><pre>
178// Simple example using typemaps
179%module example
180%include "typemaps.i"
181
182%{
183extern void add(double a, double b, double *OUTPUT);
184%}
185extern void add(double a, double b, double *OUTPUT);
186</pre></div>
187
188<p>
189Typemaps stay in effect until they are explicitly deleted or redefined to something
190else. To clear a typemap, the <tt>%clear</tt> directive should be used. For example:
191</p>
192
193<div class="code">
194<pre>
195%clear double *result; // Remove all typemaps for double *result
196</pre>
197</div>
198
199<H3><a name="Arguments_nn4"></a>9.1.2 Input parameters</H3>
200
201
202<p>
203The following typemaps instruct SWIG that a pointer really only holds a single
204input value:
205</p>
206
207<div class="code"><pre>
208int *INPUT
209short *INPUT
210long *INPUT
211unsigned int *INPUT
212unsigned short *INPUT
213unsigned long *INPUT
214double *INPUT
215float *INPUT
216</pre></div>
217
218<p>
219When used, it allows values to be passed instead of pointers. For example, consider this
220function:
221</p>
222
223<div class="code"><pre>
224double add(double *a, double *b) {
225 return *a+*b;
226}
227</pre></div>
228
229<p>
230Now, consider this SWIG interface:
231</p>
232
233<div class="code"><pre>
234%module example
235%include "typemaps.i"
236...
237%{
238extern double add(double *, double *);
239%}
240extern double add(double *INPUT, double *INPUT);
241
242</pre></div>
243
244<p>
245When the function is used in the scripting language interpreter, it will work like this:
246</p>
247
248<div class="targetlang"><pre>
249result = add(3,4)
250</pre></div>
251
252<H3><a name="Arguments_nn5"></a>9.1.3 Output parameters</H3>
253
254
255<p>
256The following typemap rules tell SWIG that pointer is the output value of a
257function. When used, you do not need to supply the argument when
258calling the function. Instead, one or more output values are returned.
259</p>
260
261<div class="code"><pre>
262int *OUTPUT
263short *OUTPUT
264long *OUTPUT
265unsigned int *OUTPUT
266unsigned short *OUTPUT
267unsigned long *OUTPUT
268double *OUTPUT
269float *OUTPUT
270
271</pre></div>
272<p>
273These methods can be used as shown in an earlier example. For example, if you have this C function :</p>
274
275<div class="code"><pre>
276void add(double a, double b, double *c) {
277 *c = a+b;
278}
279</pre></div>
280
281<p>
282A SWIG interface file might look like this :</p>
283
284<div class="code"><pre>
285%module example
286%include "typemaps.i"
287...
288%inline %{
289extern void add(double a, double b, double *OUTPUT);
290%}
291
292</pre></div>
293
294<p>
295In this case, only a single output value is returned, but this is not
296a restriction. An arbitrary number of output values can be returned by applying
297the output rules to more than one argument (as shown previously).
298</p>
299
300<p>
301If the function also returns a value, it is returned along with the argument. For example,
302if you had this:
303</p>
304
305<div class="code"><pre>
306extern int foo(double a, double b, double *OUTPUT);
307</pre></div>
308
309<p>
310The function will return two values like this:
311</p>
312
313<div class="targetlang">
314<pre>
315iresult, dresult = foo(3.5, 2)
316</pre>
317</div>
318
319<H3><a name="Arguments_nn6"></a>9.1.4 Input/Output parameters</H3>
320
321
322<p>
323When a pointer serves as both an input and output value you can use
324the following typemaps :</p>
325
326<div class="code"><pre>
327int *INOUT
328short *INOUT
329long *INOUT
330unsigned int *INOUT
331unsigned short *INOUT
332unsigned long *INOUT
333double *INOUT
334float *INOUT
335
336</pre></div>
337
338<p>
339A C function that uses this might be something like this:</p>
340
341<div class="code"><pre>
342void negate(double *x) {
343 *x = -(*x);
344}
345
346</pre></div>
347
348<p>
349To make x function as both and input and output value, declare the
350function like this in an interface file :</p>
351
352<div class="code"><pre>
353%module example
354%include typemaps.i
355...
356%{
357extern void negate(double *);
358%}
359extern void negate(double *INOUT);
360
361</pre></div>
362
363<p>
364Now within a script, you can simply call the function normally :</p>
365
366<div class="targetlang"><pre>
367a = negate(3); # a = -3 after calling this
368</pre></div>
369
370<p>
371One subtle point of the <tt>INOUT</tt> rule is that many scripting languages
372enforce mutability constraints on primitive objects (meaning that simple objects
373like integers and strings aren't supposed to change). Because of this, you can't
374just modify the object's value in place as the underlying C function does in this example.
375Therefore, the <tt>INOUT</tt> rule returns the modified value as a new object
376rather than directly overwriting the value of the original input object.
377</p>
378
379<p>
380<b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
381SWIG. Backwards compatibility is preserved, but deprecated.
382</p>
383
384<H3><a name="Arguments_nn7"></a>9.1.5 Using different names</H3>
385
386
387<p>
388As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
389<tt>INOUT</tt> typemaps to different argument names. For example:
390</p>
391
392<div class="code"><pre>
393// Make double *result an output value
394%apply double *OUTPUT { double *result };
395
396// Make Int32 *in an input value
397%apply int *INPUT { Int32 *in };
398
399// Make long *x inout
400%apply long *INOUT {long *x};
401
402</pre></div>
403
404<p>
405To clear a rule, the <tt>%clear</tt> directive is used:
406</p>
407
408<div class="code"><pre>
409%clear double *result;
410%clear Int32 *in, long *x;
411</pre></div>
412
413<p>
414Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the
415file or a matching <tt>%clear</tt> declaration.
416</p>
417
418<H2><a name="Arguments_nn8"></a>9.2 Applying constraints to input values</H2>
419
420
421<p>
422In addition to changing the handling of various input values, it is
423also possible to use typemaps to apply constraints. For example, maybe you want to
424insure that a value is positive, or that a pointer is non-NULL. This
425can be accomplished including the <tt>constraints.i</tt> library file.
426</p>
427
428<H3><a name="Arguments_nn9"></a>9.2.1 Simple constraint example</H3>
429
430
431<p>
432The constraints library is best illustrated by the following interface
433file :</p>
434
435<div class="code"><pre>
436// Interface file with constraints
437%module example
438%include "constraints.i"
439
440double exp(double x);
441double log(double POSITIVE); // Allow only positive values
442double sqrt(double NONNEGATIVE); // Non-negative values only
443double inv(double NONZERO); // Non-zero values
444void free(void *NONNULL); // Non-NULL pointers only
445
446</pre></div>
447
448<p>
449The behavior of this file is exactly as you would expect. If any of
450the arguments violate the constraint condition, a scripting language
451exception will be raised. As a result, it is possible to catch bad
452values, prevent mysterious program crashes and so on.</p>
453
454<H3><a name="Arguments_nn10"></a>9.2.2 Constraint methods</H3>
455
456
457<p>
458The following constraints are currently available</p>
459
460<div class="code"><pre>
461POSITIVE Any number &gt; 0 (not zero)
462NEGATIVE Any number &lt; 0 (not zero)
463NONNEGATIVE Any number &gt;= 0
464NONPOSITIVE Any number &lt;= 0
465NONZERO Nonzero number
466NONNULL Non-NULL pointer (pointers only).
467
468</pre></div>
469
470<H3><a name="Arguments_nn11"></a>9.2.3 Applying constraints to new datatypes</H3>
471
472
473<p>
474The constraints library only supports the primitive C datatypes, but it
475is easy to apply it to new datatypes using <tt>%apply</tt>. For
476example :</p>
477
478<div class="code"><pre>
479// Apply a constraint to a Real variable
480%apply Number POSITIVE { Real in };
481
482// Apply a constraint to a pointer type
483%apply Pointer NONNULL { Vector * };
484
485</pre></div>
486
487<p>
488The special types of "Number" and "Pointer" can be applied to any
489numeric and pointer variable type respectively. To later remove a
490constraint, the <tt>%clear</tt> directive can be used :</p>
491
492<div class="code"><pre>
493%clear Real in;
494%clear Vector *;
495</pre></div>
496
497</body>
498</html>