Commit | Line | Data |
---|---|---|
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> | |
36 | In Chapter 3, SWIG's treatment of basic datatypes and pointers was | |
37 | described. In particular, primitive types such as <tt>int</tt> and | |
38 | <tt>double</tt> are mapped to corresponding types in the target | |
39 | language. For everything else, pointers are used to refer to | |
40 | structures, classes, arrays, and other user-defined datatypes. | |
41 | However, in certain applications it is desirable to change SWIG's | |
42 | handling of a specific datatype. For example, you might want to | |
43 | return multiple values through the arguments of a function. This chapter | |
44 | describes 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> | |
51 | This section describes the <tt>typemaps.i</tt> library file--commonly used to | |
52 | change certain properties of argument conversion. | |
53 | </p> | |
54 | ||
55 | <H3><a name="Arguments_nn3"></a>9.1.1 Introduction</H3> | |
56 | ||
57 | ||
58 | <p> | |
59 | Suppose you had a C function like this: | |
60 | </p> | |
61 | ||
62 | <div class="code"><pre> | |
63 | void add(double a, double b, double *result) { | |
64 | *result = a + b; | |
65 | } | |
66 | </pre></div> | |
67 | ||
68 | <p> | |
69 | From reading the source code, it is clear that the function is storing | |
70 | a value in the <tt>double *result</tt> parameter. However, since SWIG | |
71 | does not examine function bodies, it has no way to know that this is | |
72 | the underlying behavior. | |
73 | </p> | |
74 | ||
75 | <p> | |
76 | One 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 %{ | |
87 | extern void add(double a, double b, double *result); | |
88 | %} | |
89 | </pre></div> | |
90 | ||
91 | <p> | |
92 | The <tt>%apply</tt> directive tells SWIG that you are going to apply | |
93 | a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the | |
94 | name 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 | |
96 | listed in curly braces-- in this case "<tt>double *result</tt>".</p> | |
97 | ||
98 | <p> | |
99 | When the resulting module is created, you can now use the function | |
100 | like this (shown for Python): | |
101 | </p> | |
102 | ||
103 | <div class="targetlang"><pre> | |
104 | >>> a = add(3,4) | |
105 | >>> print a | |
106 | 7 | |
107 | >>> | |
108 | </pre></div> | |
109 | ||
110 | <p> | |
111 | In this case, you can see how the output value normally returned in | |
112 | the third argument has magically been transformed into a function | |
113 | return value. Clearly this makes the function much easier to use | |
114 | since 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> | |
119 | Once a typemap has been applied to a type, it stays in effect for all future occurrences | |
120 | of 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 %{ | |
130 | extern void add(double a, double b, double *result); | |
131 | extern void sub(double a, double b, double *result); | |
132 | extern void mul(double a, double b, double *result); | |
133 | extern void div(double a, double b, double *result); | |
134 | %} | |
135 | ... | |
136 | </pre></div> | |
137 | ||
138 | <p> | |
139 | In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow. | |
140 | </p> | |
141 | ||
142 | <p> | |
143 | Typemap transformations can even be extended to multiple return values. | |
144 | For 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) | |
153 | void getwinsize(int winid, int *width, int *height); | |
154 | </pre> | |
155 | </div> | |
156 | ||
157 | <p> | |
158 | In this case, the function returns multiple values, allowing it to be used like this: | |
159 | </p> | |
160 | ||
161 | <div class="targetlang"><pre> | |
162 | >>> w,h = genwinsize(wid) | |
163 | >>> print w | |
164 | 400 | |
165 | >>> print h | |
166 | 300 | |
167 | >>> | |
168 | </pre> | |
169 | </div> | |
170 | ||
171 | <p> | |
172 | It should also be noted that although the <tt>%apply</tt> directive is | |
173 | used to associate typemap rules to datatypes, you can also use the | |
174 | rule 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 | %{ | |
183 | extern void add(double a, double b, double *OUTPUT); | |
184 | %} | |
185 | extern void add(double a, double b, double *OUTPUT); | |
186 | </pre></div> | |
187 | ||
188 | <p> | |
189 | Typemaps stay in effect until they are explicitly deleted or redefined to something | |
190 | else. 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> | |
203 | The following typemaps instruct SWIG that a pointer really only holds a single | |
204 | input value: | |
205 | </p> | |
206 | ||
207 | <div class="code"><pre> | |
208 | int *INPUT | |
209 | short *INPUT | |
210 | long *INPUT | |
211 | unsigned int *INPUT | |
212 | unsigned short *INPUT | |
213 | unsigned long *INPUT | |
214 | double *INPUT | |
215 | float *INPUT | |
216 | </pre></div> | |
217 | ||
218 | <p> | |
219 | When used, it allows values to be passed instead of pointers. For example, consider this | |
220 | function: | |
221 | </p> | |
222 | ||
223 | <div class="code"><pre> | |
224 | double add(double *a, double *b) { | |
225 | return *a+*b; | |
226 | } | |
227 | </pre></div> | |
228 | ||
229 | <p> | |
230 | Now, consider this SWIG interface: | |
231 | </p> | |
232 | ||
233 | <div class="code"><pre> | |
234 | %module example | |
235 | %include "typemaps.i" | |
236 | ... | |
237 | %{ | |
238 | extern double add(double *, double *); | |
239 | %} | |
240 | extern double add(double *INPUT, double *INPUT); | |
241 | ||
242 | </pre></div> | |
243 | ||
244 | <p> | |
245 | When the function is used in the scripting language interpreter, it will work like this: | |
246 | </p> | |
247 | ||
248 | <div class="targetlang"><pre> | |
249 | result = add(3,4) | |
250 | </pre></div> | |
251 | ||
252 | <H3><a name="Arguments_nn5"></a>9.1.3 Output parameters</H3> | |
253 | ||
254 | ||
255 | <p> | |
256 | The following typemap rules tell SWIG that pointer is the output value of a | |
257 | function. When used, you do not need to supply the argument when | |
258 | calling the function. Instead, one or more output values are returned. | |
259 | </p> | |
260 | ||
261 | <div class="code"><pre> | |
262 | int *OUTPUT | |
263 | short *OUTPUT | |
264 | long *OUTPUT | |
265 | unsigned int *OUTPUT | |
266 | unsigned short *OUTPUT | |
267 | unsigned long *OUTPUT | |
268 | double *OUTPUT | |
269 | float *OUTPUT | |
270 | ||
271 | </pre></div> | |
272 | <p> | |
273 | These 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> | |
276 | void add(double a, double b, double *c) { | |
277 | *c = a+b; | |
278 | } | |
279 | </pre></div> | |
280 | ||
281 | <p> | |
282 | A SWIG interface file might look like this :</p> | |
283 | ||
284 | <div class="code"><pre> | |
285 | %module example | |
286 | %include "typemaps.i" | |
287 | ... | |
288 | %inline %{ | |
289 | extern void add(double a, double b, double *OUTPUT); | |
290 | %} | |
291 | ||
292 | </pre></div> | |
293 | ||
294 | <p> | |
295 | In this case, only a single output value is returned, but this is not | |
296 | a restriction. An arbitrary number of output values can be returned by applying | |
297 | the output rules to more than one argument (as shown previously). | |
298 | </p> | |
299 | ||
300 | <p> | |
301 | If the function also returns a value, it is returned along with the argument. For example, | |
302 | if you had this: | |
303 | </p> | |
304 | ||
305 | <div class="code"><pre> | |
306 | extern int foo(double a, double b, double *OUTPUT); | |
307 | </pre></div> | |
308 | ||
309 | <p> | |
310 | The function will return two values like this: | |
311 | </p> | |
312 | ||
313 | <div class="targetlang"> | |
314 | <pre> | |
315 | iresult, 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> | |
323 | When a pointer serves as both an input and output value you can use | |
324 | the following typemaps :</p> | |
325 | ||
326 | <div class="code"><pre> | |
327 | int *INOUT | |
328 | short *INOUT | |
329 | long *INOUT | |
330 | unsigned int *INOUT | |
331 | unsigned short *INOUT | |
332 | unsigned long *INOUT | |
333 | double *INOUT | |
334 | float *INOUT | |
335 | ||
336 | </pre></div> | |
337 | ||
338 | <p> | |
339 | A C function that uses this might be something like this:</p> | |
340 | ||
341 | <div class="code"><pre> | |
342 | void negate(double *x) { | |
343 | *x = -(*x); | |
344 | } | |
345 | ||
346 | </pre></div> | |
347 | ||
348 | <p> | |
349 | To make x function as both and input and output value, declare the | |
350 | function like this in an interface file :</p> | |
351 | ||
352 | <div class="code"><pre> | |
353 | %module example | |
354 | %include typemaps.i | |
355 | ... | |
356 | %{ | |
357 | extern void negate(double *); | |
358 | %} | |
359 | extern void negate(double *INOUT); | |
360 | ||
361 | </pre></div> | |
362 | ||
363 | <p> | |
364 | Now within a script, you can simply call the function normally :</p> | |
365 | ||
366 | <div class="targetlang"><pre> | |
367 | a = negate(3); # a = -3 after calling this | |
368 | </pre></div> | |
369 | ||
370 | <p> | |
371 | One subtle point of the <tt>INOUT</tt> rule is that many scripting languages | |
372 | enforce mutability constraints on primitive objects (meaning that simple objects | |
373 | like integers and strings aren't supposed to change). Because of this, you can't | |
374 | just modify the object's value in place as the underlying C function does in this example. | |
375 | Therefore, the <tt>INOUT</tt> rule returns the modified value as a new object | |
376 | rather 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 | |
381 | SWIG. 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> | |
388 | As 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> | |
405 | To 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> | |
414 | Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the | |
415 | file 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> | |
422 | In addition to changing the handling of various input values, it is | |
423 | also possible to use typemaps to apply constraints. For example, maybe you want to | |
424 | insure that a value is positive, or that a pointer is non-NULL. This | |
425 | can 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> | |
432 | The constraints library is best illustrated by the following interface | |
433 | file :</p> | |
434 | ||
435 | <div class="code"><pre> | |
436 | // Interface file with constraints | |
437 | %module example | |
438 | %include "constraints.i" | |
439 | ||
440 | double exp(double x); | |
441 | double log(double POSITIVE); // Allow only positive values | |
442 | double sqrt(double NONNEGATIVE); // Non-negative values only | |
443 | double inv(double NONZERO); // Non-zero values | |
444 | void free(void *NONNULL); // Non-NULL pointers only | |
445 | ||
446 | </pre></div> | |
447 | ||
448 | <p> | |
449 | The behavior of this file is exactly as you would expect. If any of | |
450 | the arguments violate the constraint condition, a scripting language | |
451 | exception will be raised. As a result, it is possible to catch bad | |
452 | values, 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> | |
458 | The following constraints are currently available</p> | |
459 | ||
460 | <div class="code"><pre> | |
461 | POSITIVE Any number > 0 (not zero) | |
462 | NEGATIVE Any number < 0 (not zero) | |
463 | NONNEGATIVE Any number >= 0 | |
464 | NONPOSITIVE Any number <= 0 | |
465 | NONZERO Nonzero number | |
466 | NONNULL 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> | |
474 | The constraints library only supports the primitive C datatypes, but it | |
475 | is easy to apply it to new datatypes using <tt>%apply</tt>. For | |
476 | example :</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> | |
488 | The special types of "Number" and "Pointer" can be applied to any | |
489 | numeric and pointer variable type respectively. To later remove a | |
490 | constraint, 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> |