Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>Variable Length Arguments</title> | |
5 | <link rel="stylesheet" type="text/css" href="style.css"> | |
6 | </head> | |
7 | ||
8 | <body bgcolor="#ffffff"> | |
9 | <H1><a name="Varargs"></a>13 Variable Length Arguments</H1> | |
10 | <!-- INDEX --> | |
11 | <div class="sectiontoc"> | |
12 | <ul> | |
13 | <li><a href="#Varargs_nn2">Introduction</a> | |
14 | <li><a href="#Varargs_nn3">The Problem</a> | |
15 | <li><a href="#Varargs_nn4">Default varargs support</a> | |
16 | <li><a href="#Varargs_nn5">Argument replacement using %varargs</a> | |
17 | <li><a href="#Varargs_nn6">Varargs and typemaps</a> | |
18 | <li><a href="#Varargs_nn7">Varargs wrapping with libffi</a> | |
19 | <li><a href="#Varargs_nn8">Wrapping of va_list</a> | |
20 | <li><a href="#Varargs_nn9">C++ Issues</a> | |
21 | <li><a href="#Varargs_nn10">Discussion</a> | |
22 | </ul> | |
23 | </div> | |
24 | <!-- INDEX --> | |
25 | ||
26 | ||
27 | ||
28 | <p> | |
29 | <b>(a.k.a, "The horror. The horror.")</b> | |
30 | </p> | |
31 | ||
32 | <p> | |
33 | This chapter describes the problem of wrapping functions that take a | |
34 | variable number of arguments. For instance, generating wrappers for | |
35 | the C <tt>printf()</tt> family of functions. | |
36 | </p> | |
37 | ||
38 | <p> | |
39 | This topic is sufficiently advanced to merit its own chapter. In | |
40 | fact, support for varargs is an often requested feature that was first | |
41 | added in SWIG-1.3.12. Most other wrapper generation tools have | |
42 | wisely chosen to avoid this issue. | |
43 | </p> | |
44 | ||
45 | <H2><a name="Varargs_nn2"></a>13.1 Introduction</H2> | |
46 | ||
47 | ||
48 | <p> | |
49 | Some C and C++ programs may include functions that accept a variable | |
50 | number of arguments. For example, most programmers are | |
51 | familiar with functions from the C library such as the following: | |
52 | </p> | |
53 | ||
54 | <div class="code"> | |
55 | <pre> | |
56 | int printf(const char *fmt, ...) | |
57 | int fprintf(FILE *, const char *fmt, ...); | |
58 | int sprintf(char *s, const char *fmt, ...); | |
59 | </pre> | |
60 | </div> | |
61 | ||
62 | <p> | |
63 | Although there is probably little practical purpose in wrapping these | |
64 | specific C library functions in a scripting language (what would be the | |
65 | point?), a library may include its own set of special functions based | |
66 | on a similar API. For example: | |
67 | </p> | |
68 | ||
69 | <div class="code"> | |
70 | <pre> | |
71 | int traceprintf(const char *fmt, ...); | |
72 | </pre> | |
73 | </div> | |
74 | ||
75 | <p> | |
76 | In this case, you may want to have some kind of access from the target language. | |
77 | </p> | |
78 | ||
79 | <p> | |
80 | Before describing the SWIG implementation, it is important to discuss | |
81 | the common uses of varargs that you are likely to encounter in real | |
82 | programs. Obviously, there are the <tt>printf()</tt> style output | |
83 | functions as shown. Closely related to this would be | |
84 | <tt>scanf()</tt> style input functions that accept a format string and a | |
85 | list of pointers into which return values are placed. However, variable | |
86 | length arguments are also sometimes used to write functions that accept a | |
87 | NULL-terminated list of pointers. A good example of this would | |
88 | be a function like this: | |
89 | </p> | |
90 | ||
91 | <div class="code"> | |
92 | <pre> | |
93 | int execlp(const char *path, const char *arg1, ...); | |
94 | ... | |
95 | ||
96 | /* Example */ | |
97 | execlp("ls","ls","-l",NULL); | |
98 | </pre> | |
99 | </div> | |
100 | ||
101 | <p> | |
102 | In addition, varargs is sometimes used to fake default arguments in older | |
103 | C libraries. For instance, the low level <tt>open()</tt> system call | |
104 | is often declared as a varargs function so that it will accept two | |
105 | or three arguments: | |
106 | </p> | |
107 | ||
108 | <div class="code"> | |
109 | <pre> | |
110 | int open(const char *path, int oflag, ...); | |
111 | ... | |
112 | ||
113 | /* Examples */ | |
114 | f = open("foo", O_RDONLY); | |
115 | g = open("bar", O_WRONLY | O_CREAT, 0644); | |
116 | </pre> | |
117 | </div> | |
118 | ||
119 | <p> | |
120 | Finally, to implement a varargs function, recall that you have to use | |
121 | the C library functions defined in <tt><stdarg.h></tt>. For | |
122 | example: | |
123 | </p> | |
124 | ||
125 | <div class="code"> | |
126 | <pre> | |
127 | List make_list(const char *s, ...) { | |
128 | va_list ap; | |
129 | List x; | |
130 | ... | |
131 | va_start(ap, s); | |
132 | while (s) { | |
133 | x.append(s); | |
134 | s = va_arg(ap, const char *); | |
135 | } | |
136 | va_end(ap); | |
137 | return x; | |
138 | } | |
139 | </pre> | |
140 | </div> | |
141 | ||
142 | <H2><a name="Varargs_nn3"></a>13.2 The Problem</H2> | |
143 | ||
144 | ||
145 | <p> | |
146 | Generating wrappers for a variable length argument function presents a | |
147 | number of special challenges. Although C provides support for | |
148 | implementing functions that receive variable length arguments, there | |
149 | are no functions that can go in the other direction. Specifically, | |
150 | you can't write a function that dynamically creates a list of | |
151 | arguments and which invokes a varargs function on your behalf. | |
152 | </p> | |
153 | ||
154 | <p> | |
155 | Although it is possible to write functions that accept the special | |
156 | type <tt>va_list</tt>, this is something entirely different. You | |
157 | can't take a <tt>va_list</tt> structure and pass it in place of the | |
158 | variable length arguments to another varargs function. It just | |
159 | doesn't work. | |
160 | </p> | |
161 | ||
162 | <p> | |
163 | The reason this doesn't work has to do with the way that function | |
164 | calls get compiled. For example, suppose that your program has a function call like this: | |
165 | </p> | |
166 | ||
167 | <div class="code"> | |
168 | <pre> | |
169 | printf("Hello %s. Your number is %d\n", name, num); | |
170 | </pre> | |
171 | </div> | |
172 | ||
173 | <p> | |
174 | When the compiler looks at this, it knows that you are calling | |
175 | <tt>printf()</tt> with exactly three arguments. Furthermore, it knows | |
176 | that the number of arguments as well are their types and sizes is | |
177 | <em>never</em> going to change during program execution. Therefore, | |
178 | this gets turned to machine code that sets up a three-argument stack | |
179 | frame followed by a call to <tt>printf()</tt>. | |
180 | </p> | |
181 | ||
182 | <p> | |
183 | In contrast, suppose you attempted to make some kind of wrapper around | |
184 | <tt>printf()</tt> using code like this: | |
185 | </p> | |
186 | ||
187 | <div class="code"> | |
188 | <pre> | |
189 | int wrap_printf(const char *fmt, ...) { | |
190 | va_list ap; | |
191 | va_start(ap,fmt); | |
192 | ... | |
193 | printf(fmt,ap); | |
194 | ... | |
195 | va_end(ap); | |
196 | }; | |
197 | </pre> | |
198 | </div> | |
199 | ||
200 | <p> | |
201 | Athough this code might compile, it won't do what you expect. This is | |
202 | because the call to <tt>printf()</tt> is compiled as a procedure call | |
203 | involving only two arguments. However, clearly a two-argument | |
204 | configuration of the call stack is completely wrong if your intent is | |
205 | to pass an arbitrary number of arguments to the real | |
206 | <tt>printf()</tt>. Needless to say, it won't work. | |
207 | </p> | |
208 | ||
209 | <p> | |
210 | Unfortunately, the situation just described is exactly the problem | |
211 | faced by wrapper generation tools. In general, the number of passed | |
212 | arguments will not be known until run-time. To make matters even | |
213 | worse, you won't know the types and sizes of arguments until run-time | |
214 | as well. Needless to say, there is no obvious way to make the C | |
215 | compiler generate code for a function call involving an unknown number | |
216 | of arguments of unknown types. | |
217 | </p> | |
218 | ||
219 | <p> | |
220 | In theory, it <em>is</em> possible to write a wrapper that does the right thing. | |
221 | However, this involves knowing the underlying ABI for the target platform and language | |
222 | as well as writing special purpose code that manually constructed the call stack before | |
223 | making a procedure call. Unfortunately, both of these tasks require the use of inline | |
224 | assembly code. Clearly, that's the kind of solution you would much rather avoid. | |
225 | </p> | |
226 | ||
227 | <p> | |
228 | With this nastiness in mind, SWIG provides a number of solutions to the varargs | |
229 | wrapping problem. Most of these solutions are compromises that provide limited | |
230 | varargs support without having to resort to assembly language. However, SWIG | |
231 | can also support real varargs wrapping (with stack-frame manipulation) if you | |
232 | are willing to get hands dirty. Keep reading. | |
233 | </p> | |
234 | ||
235 | <H2><a name="Varargs_nn4"></a>13.3 Default varargs support</H2> | |
236 | ||
237 | ||
238 | <p> | |
239 | When variable length arguments appear in an interface, the default | |
240 | behavior is to drop the variable argument list entirely, replacing | |
241 | them with a single NULL pointer. For example, if you had this | |
242 | function, | |
243 | </p> | |
244 | ||
245 | <div class="code"> | |
246 | <pre> | |
247 | void traceprintf(const char *fmt, ...); | |
248 | </pre> | |
249 | </div> | |
250 | ||
251 | <p> | |
252 | it would be wrapped as if it had been declared as follows: | |
253 | </p> | |
254 | ||
255 | <div class="code"> | |
256 | <pre> | |
257 | void traceprintf(const char *fmt); | |
258 | </pre> | |
259 | </div> | |
260 | ||
261 | <p> | |
262 | When the function is called inside the wrappers, it is called as follows: | |
263 | </p> | |
264 | ||
265 | <div class="code"> | |
266 | <pre> | |
267 | traceprintf(arg1, NULL); | |
268 | </pre> | |
269 | </div> | |
270 | ||
271 | <p> | |
272 | Arguably, this approach seems to defeat the whole point of variable length arguments. However, | |
273 | this actually provides enough support for many simple kinds of varargs functions to still be useful. For | |
274 | instance, you could make function calls like this (in Python): | |
275 | </p> | |
276 | ||
277 | <div class="targetlang"> | |
278 | <pre> | |
279 | >>> traceprintf("Hello World") | |
280 | >>> traceprintf("Hello %s. Your number is %d\n" % (name, num)) | |
281 | </pre> | |
282 | </div> | |
283 | ||
284 | <p> | |
285 | Notice how string formatting is being done in Python instead of C. | |
286 | </p> | |
287 | ||
288 | <H2><a name="Varargs_nn5"></a>13.4 Argument replacement using %varargs</H2> | |
289 | ||
290 | ||
291 | <p> | |
292 | Instead of dropping the variable length arguments, an alternative approach is to replace | |
293 | <tt>(...)</tt> with a set of suitable arguments. SWIG provides a special <tt>%varargs</tt> directive | |
294 | that can be used to do this. For example, | |
295 | </p> | |
296 | ||
297 | <div class="code"> | |
298 | <pre> | |
299 | %varargs(int mode = 0) open; | |
300 | ... | |
301 | int open(const char *path, int oflags, ...); | |
302 | </pre> | |
303 | </div> | |
304 | ||
305 | <p> | |
306 | is equivalent to this: | |
307 | </p> | |
308 | ||
309 | <div class="code"> | |
310 | <pre> | |
311 | int open(const char *path, int oflags, int mode = 0); | |
312 | </pre> | |
313 | </div> | |
314 | ||
315 | <p> | |
316 | In this case, <tt>%varargs</tt> is simply providing more specific information about the | |
317 | extra arguments that might be passed to a function. | |
318 | If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also | |
319 | accept a numerical argument count as follows: | |
320 | </p> | |
321 | ||
322 | <div class="code"> | |
323 | <pre> | |
324 | %varargs(10,char *arg = NULL) execlp; | |
325 | ... | |
326 | int execlp(const char *path, const char *arg1, ...); | |
327 | </pre> | |
328 | </div> | |
329 | ||
330 | <p> | |
331 | This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments. | |
332 | Depending on the application, this may be more than enough for practical purposes. | |
333 | </p> | |
334 | ||
335 | <p> | |
336 | Argument replacement is most appropriate in cases where the types of | |
337 | the extra arguments is uniform and the maximum number of arguments is | |
338 | known. When replicated argument replacement is used, at least one extra | |
339 | argument is added to the end of the arguments when making the function call. | |
340 | This argument serves as a sentinel to make sure the list is properly terminated. | |
341 | It has the same value as that supplied to the <tt>%varargs</tt> directive. | |
342 | </p> | |
343 | ||
344 | <p> | |
345 | Argument replacement is not as useful when working with functions that accept | |
346 | mixed argument types such as <tt>printf()</tt>. Providing general purpose | |
347 | wrappers to such functions presents special problems (covered shortly). | |
348 | </p> | |
349 | ||
350 | <H2><a name="Varargs_nn6"></a>13.5 Varargs and typemaps</H2> | |
351 | ||
352 | ||
353 | <p> | |
354 | Variable length arguments may be used in typemap specifications. For example: | |
355 | </p> | |
356 | ||
357 | <div class="code"> | |
358 | <pre> | |
359 | %typemap(in) (...) { | |
360 | // Get variable length arguments (somehow) | |
361 | ... | |
362 | } | |
363 | ||
364 | %typemap(in) (const char *fmt, ...) { | |
365 | // Multi-argument typemap | |
366 | } | |
367 | </pre> | |
368 | </div> | |
369 | ||
370 | <p> | |
371 | However, this immediately raises the question of what "type" is actually used | |
372 | to represent <tt>(...)</tt>. For lack of a better alternative, the type of | |
373 | <tt>(...)</tt> is set to <tt>void *</tt>. Since there is no | |
374 | way to dynamically pass arguments to a varargs function (as previously described), | |
375 | the <tt>void *</tt> argument value is intended to serve as a place holder | |
376 | for storing some kind of information about the extra arguments (if any). In addition, the | |
377 | default behavior of SWIG is to pass the <tt>void *</tt> value as an argument to | |
378 | the function. Therefore, you could use the pointer to hold a valid argument value if you wanted. | |
379 | </p> | |
380 | ||
381 | <p> | |
382 | To illustrate, here is a safer version of wrapping <tt>printf()</tt> in Python: | |
383 | </p> | |
384 | ||
385 | <div class="code"> | |
386 | <pre> | |
387 | %typemap(in) (const char *fmt, ...) { | |
388 | $1 = "%s"; /* Fix format string to %s */ | |
389 | $2 = (void *) PyString_AsString($input); /* Get string argument */ | |
390 | }; | |
391 | ... | |
392 | int printf(const char *fmt, ...); | |
393 | </pre> | |
394 | </div> | |
395 | ||
396 | <p> | |
397 | In this example, the format string is implicitly set to <tt>"%s"</tt>. | |
398 | This prevents a program from passing a bogus format string to the | |
399 | extension. Then, the passed input object is decoded and placed in the | |
400 | <tt>void *</tt> argument defined for the <tt>(...)</tt> argument. When the | |
401 | actual function call is made, the underlying wrapper code will look roughly | |
402 | like this: | |
403 | </p> | |
404 | ||
405 | <div class="code"> | |
406 | <pre> | |
407 | wrap_printf() { | |
408 | char *arg1; | |
409 | void *arg2; | |
410 | int result; | |
411 | ||
412 | arg1 = "%s"; | |
413 | arg2 = (void *) PyString_AsString(arg2obj); | |
414 | ... | |
415 | result = printf(arg1,arg2); | |
416 | ... | |
417 | } | |
418 | </pre> | |
419 | </div> | |
420 | ||
421 | <p> | |
422 | Notice how both arguments are passed to the function and it does what you | |
423 | would expect. | |
424 | </p> | |
425 | ||
426 | <p> | |
427 | The next example illustrates a more advanced kind of varargs typemap. | |
428 | Disclaimer: this requires special support in the target language module and is not | |
429 | guaranteed to work with all SWIG modules at this time. It also starts to illustrate | |
430 | some of the more fundamental problems with supporting varargs in more generality. | |
431 | </p> | |
432 | ||
433 | <p> | |
434 | If a typemap is defined for any form of <tt>(...)</tt>, many SWIG | |
435 | modules will generate wrappers that accept a variable number of | |
436 | arguments as input and will make these arguments available in some | |
437 | form. The precise details of this depends on the language module | |
438 | being used (consult the appropriate chapter for more details). | |
439 | However, suppose that you wanted to create a Python wrapper for the | |
440 | <tt>execlp()</tt> function shown earlier. To do this using a typemap | |
441 | instead of using <tt>%varargs</tt>, you might first write a typemap | |
442 | like this: | |
443 | </p> | |
444 | ||
445 | <div class="code"> | |
446 | <pre> | |
447 | %typemap(in) (...)(char *args[10]) { | |
448 | int i; | |
449 | int argc; | |
450 | for (i = 0; i < 10; i++) args[i] = 0; | |
451 | argc = PyTuple_Size(varargs); | |
452 | if (argc > 10) { | |
453 | PyErr_SetString(PyExc_ValueError,"Too many arguments"); | |
454 | return NULL; | |
455 | } | |
456 | for (i = 0; i < argc; i++) { | |
457 | PyObject *o = PyTuple_GetItem(varargs,i); | |
458 | if (!PyString_Check(o)) { | |
459 | PyErr_SetString(PyExc_ValueError,"Expected a string"); | |
460 | return NULL; | |
461 | } | |
462 | args[i] = PyString_AsString(o); | |
463 | } | |
464 | $1 = (void *) args; | |
465 | } | |
466 | </pre> | |
467 | </div> | |
468 | ||
469 | <p> | |
470 | In this typemap, the special variable <tt>varargs</tt> is a tuple | |
471 | holding all of the extra arguments passed (this is specific to the | |
472 | Python module). The typemap then pulls this apart and sticks the | |
473 | values into the array of strings <tt>args</tt>. Then, the array is | |
474 | assigned to <tt>$1</tt> (recall that this is the <tt>void *</tt> | |
475 | variable corresponding to <tt>(...)</tt>). However, this assignment | |
476 | is only half of the picture----clearly this alone is not enough to | |
477 | make the function work. To patch everything up, you have to rewrite the | |
478 | underlying action code using the <tt>%feature</tt> directive like | |
479 | this: | |
480 | </p> | |
481 | ||
482 | <div class="code"> | |
483 | <pre> | |
484 | %feature("action") execlp { | |
485 | char *args = (char **) arg3; | |
486 | result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4], | |
487 | args[5],args[6],args[7],args[8],args[9], NULL); | |
488 | } | |
489 | ||
490 | int execlp(const char *path, const char *arg, ...); | |
491 | </pre> | |
492 | </div> | |
493 | ||
494 | <p> | |
495 | This patches everything up and creates a function that more or less | |
496 | works. However, don't try explaining this to your coworkers unless | |
497 | you know for certain that they've had several cups of coffee. If you | |
498 | really want to elevate your guru status and increase your job | |
499 | security, continue to the next section. | |
500 | </p> | |
501 | ||
502 | <H2><a name="Varargs_nn7"></a>13.6 Varargs wrapping with libffi</H2> | |
503 | ||
504 | ||
505 | <p> | |
506 | All of the previous examples have relied on features of SWIG that are | |
507 | portable and which don't rely upon any low-level machine-level | |
508 | details. In many ways, they have all dodged the real issue of variable | |
509 | length arguments by recasting a varargs function into some weaker variation | |
510 | with a fixed number of arguments of known types. In many cases, this | |
511 | works perfectly fine. However, if you want more generality than this, | |
512 | you need to bring out some bigger guns. | |
513 | </p> | |
514 | ||
515 | <p> | |
516 | One way to do this is to use a special purpose library such as libffi | |
517 | (<a | |
518 | href="http://sources.redhat.com/libffi/">http://sources.redhat.com/libffi</a>). | |
519 | libffi is a library that allows you to dynamically construct | |
520 | call-stacks and invoke procedures in a relatively platform independent | |
521 | manner. Details about the library can be found in the libffi | |
522 | distribution and are not repeated here. | |
523 | </p> | |
524 | ||
525 | <p> | |
526 | To illustrate the use of libffi, suppose that you <em>really</em> wanted to create a | |
527 | wrapper for <tt>execlp()</tt> that accepted <em>any</em> number of | |
528 | arguments. To do this, you might make a few adjustments to the previous | |
529 | example. For example: | |
530 | </p> | |
531 | ||
532 | <div class="code"> | |
533 | <pre> | |
534 | /* Take an arbitrary number of extra arguments and place into an array | |
535 | of strings */ | |
536 | ||
537 | %typemap(in) (...) { | |
538 | char **argv; | |
539 | int argc; | |
540 | int i; | |
541 | ||
542 | argc = PyTuple_Size(varargs); | |
543 | argv = (char **) malloc(sizeof(char *)*(argc+1)); | |
544 | for (i = 0; i < argc; i++) { | |
545 | PyObject *o = PyTuple_GetItem(varargs,i); | |
546 | if (!PyString_Check(o)) { | |
547 | PyErr_SetString(PyExc_ValueError,"Expected a string"); | |
548 | free(argv); | |
549 | return NULL; | |
550 | } | |
551 | argv[i] = PyString_AsString(o); | |
552 | } | |
553 | argv[i] = NULL; | |
554 | $1 = (void *) argv; | |
555 | } | |
556 | ||
557 | /* Rewrite the function call, using libffi */ | |
558 | ||
559 | %feature("action") execlp { | |
560 | int i, vc; | |
561 | ffi_cif cif; | |
562 | ffi_type **types; | |
563 | void **values; | |
564 | char **args; | |
565 | ||
566 | vc = PyTuple_Size(varargs); | |
567 | types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *)); | |
568 | values = (void **) malloc((vc+3)*sizeof(void *)); | |
569 | args = (char **) arg3; | |
570 | ||
571 | /* Set up path parameter */ | |
572 | types[0] = &ffi_type_pointer; | |
573 | values[0] = &arg1; | |
574 | ||
575 | /* Set up first argument */ | |
576 | types[1] = &ffi_type_pointer; | |
577 | values[1] = &arg2; | |
578 | ||
579 | /* Set up rest of parameters */ | |
580 | for (i = 0; i <= vc; i++) { | |
581 | types[2+i] = &ffi_type_pointer; | |
582 | values[2+i] = &args[i]; | |
583 | } | |
584 | if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, | |
585 | &ffi_type_uint, types) == FFI_OK) { | |
586 | ffi_call(&cif, (void (*)()) execlp, &result, values); | |
587 | } else { | |
588 | PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); | |
589 | free(types); | |
590 | free(values); | |
591 | free(arg3); | |
592 | return NULL; | |
593 | } | |
594 | free(types); | |
595 | free(values); | |
596 | free(arg3); | |
597 | } | |
598 | ||
599 | /* Declare the function. Whew! */ | |
600 | int execlp(const char *path, const char *arg1, ...); | |
601 | </pre> | |
602 | </div> | |
603 | ||
604 | <p> | |
605 | Looking at this example, you may start to wonder if SWIG is making | |
606 | life any easier. Given the amount of code involved, you might also wonder | |
607 | why you didn't just write a hand-crafted wrapper! Either that or you're wondering | |
608 | "why in the hell am I trying to wrap this varargs function in the | |
609 | first place?!?" Obviously, those are questions you'll have to answer for yourself. | |
610 | </p> | |
611 | ||
612 | <p> | |
613 | As a more extreme example of libffi, here is some code that attempts to wrap <tt>printf()</tt>, | |
614 | </p> | |
615 | ||
616 | <div class="code"> | |
617 | <pre> | |
618 | /* A wrapper for printf() using libffi */ | |
619 | ||
620 | %{ | |
621 | /* Structure for holding passed arguments after conversion */ | |
622 | typedef struct { | |
623 | int type; | |
624 | union { | |
625 | int ivalue; | |
626 | double dvalue; | |
627 | void *pvalue; | |
628 | } val; | |
629 | } vtype; | |
630 | enum { VT_INT, VT_DOUBLE, VT_POINTER }; | |
631 | %} | |
632 | ||
633 | %typemap(in) (const char *fmt, ...) { | |
634 | vtype *argv; | |
635 | int argc; | |
636 | int i; | |
637 | ||
638 | /* Format string */ | |
639 | $1 = PyString_AsString($input); | |
640 | ||
641 | /* Variable length arguments */ | |
642 | argc = PyTuple_Size(varargs); | |
643 | argv = (vtype *) malloc(argc*sizeof(vtype)); | |
644 | for (i = 0; i < argc; i++) { | |
645 | PyObject *o = PyTuple_GetItem(varargs,i); | |
646 | if (PyInt_Check(o)) { | |
647 | argv[i].type = VT_INT; | |
648 | argv[i].val.ivalue = PyInt_AsLong(o); | |
649 | } else if (PyFloat_Check(o)) { | |
650 | argv[i].type = VT_DOUBLE; | |
651 | argv[i].val.dvalue = PyFloat_AsDouble(o); | |
652 | } else if (PyString_Check(o)) { | |
653 | argv[i].type = VT_POINTER; | |
654 | argv[i].val.pvalue = (void *) PyString_AsString(o); | |
655 | } else { | |
656 | PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); | |
657 | free(argv); | |
658 | return NULL; | |
659 | } | |
660 | } | |
661 | $2 = (void *) argv; | |
662 | } | |
663 | ||
664 | /* Rewrite the function call using libffi */ | |
665 | %feature("action") printf { | |
666 | int i, vc; | |
667 | ffi_cif cif; | |
668 | ffi_type **types; | |
669 | void **values; | |
670 | vtype *args; | |
671 | ||
672 | vc = PyTuple_Size(varargs); | |
673 | types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *)); | |
674 | values = (void **) malloc((vc+1)*sizeof(void *)); | |
675 | args = (vtype *) arg2; | |
676 | ||
677 | /* Set up fmt parameter */ | |
678 | types[0] = &ffi_type_pointer; | |
679 | values[0] = &arg1; | |
680 | ||
681 | /* Set up rest of parameters */ | |
682 | for (i = 0; i < vc; i++) { | |
683 | switch(args[i].type) { | |
684 | case VT_INT: | |
685 | types[1+i] = &ffi_type_uint; | |
686 | values[1+i] = &args[i].val.ivalue; | |
687 | break; | |
688 | case VT_DOUBLE: | |
689 | types[1+i] = &ffi_type_double; | |
690 | values[1+i] = &args[i].val.dvalue; | |
691 | break; | |
692 | case VT_POINTER: | |
693 | types[1+i] = &ffi_type_pointer; | |
694 | values[1+i] = &args[i].val.pvalue; | |
695 | break; | |
696 | default: | |
697 | abort(); /* Whoa! We're seriously hosed */ | |
698 | break; | |
699 | } | |
700 | } | |
701 | if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, | |
702 | &ffi_type_uint, types) == FFI_OK) { | |
703 | ffi_call(&cif, (void (*)()) printf, &result, values); | |
704 | } else { | |
705 | PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); | |
706 | free(types); | |
707 | free(values); | |
708 | free(args); | |
709 | return NULL; | |
710 | } | |
711 | free(types); | |
712 | free(values); | |
713 | free(args); | |
714 | } | |
715 | ||
716 | /* The function */ | |
717 | int printf(const char *fmt, ...); | |
718 | </pre> | |
719 | </div> | |
720 | ||
721 | <p> | |
722 | Much to your amazement, it even seems to work if you try it: | |
723 | </p> | |
724 | ||
725 | <div class="targetlang"> | |
726 | <pre> | |
727 | >>> import example | |
728 | >>> example.printf("Grade: %s %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60) | |
729 | Grade: Dave 47/60 = 78.33% | |
730 | >>> | |
731 | </pre> | |
732 | </div> | |
733 | ||
734 | <p> | |
735 | Of course, there are still some limitations to consider: | |
736 | </p> | |
737 | ||
738 | <div class="targetlang"> | |
739 | <pre> | |
740 | >>> example.printf("la de da de da %s", 42) | |
741 | Segmentation fault (core dumped) | |
742 | </pre> | |
743 | </div> | |
744 | ||
745 | <p> | |
746 | And, on this note, we leave further exploration of libffi to the reader as an exercise. Although Python has been used as an example, | |
747 | most of the techniques in this section can be extrapolated to other language modules with a bit of work. The only | |
748 | details you need to know is how the extra arguments are accessed in each target language. For example, in the Python | |
749 | module, we used the special <tt>varargs</tt> variable to get these arguments. Modules such as Tcl8 and Perl5 simply | |
750 | provide an argument number for the first extra argument. This can be used to index into an array of passed arguments to get | |
751 | values. Please consult the chapter on each language module for more details. | |
752 | </p> | |
753 | ||
754 | <H2><a name="Varargs_nn8"></a>13.7 Wrapping of va_list</H2> | |
755 | ||
756 | ||
757 | <p> | |
758 | Closely related to variable length argument wrapping, you may encounter functions that accept a parameter | |
759 | of type <tt>va_list</tt>. For example: | |
760 | </p> | |
761 | ||
762 | <div class="code"> | |
763 | <pre> | |
764 | int vfprintf(FILE *f, const char *fmt, va_list ap); | |
765 | </pre> | |
766 | </div> | |
767 | ||
768 | <p> | |
769 | As far as we know, there is no obvious way to wrap these functions | |
770 | with SWIG. This is because there is no documented way to assemble the | |
771 | proper va_list structure (there are no C library functions to do it | |
772 | and the contents of va_list are opaque). Not only that, the contents | |
773 | of a <tt>va_list</tt> structure are closely tied to the underlying | |
774 | call-stack. It's not clear that exporting a <tt>va_list</tt> would | |
775 | have any use or that it would work at all. | |
776 | </p> | |
777 | ||
778 | <H2><a name="Varargs_nn9"></a>13.8 C++ Issues</H2> | |
779 | ||
780 | ||
781 | <p> | |
782 | Wrapping of C++ member functions that accept a variable number of | |
783 | arguments presents a number of challenges. By far, the easiest way to | |
784 | handle this is to use the <tt>%varargs</tt> directive. This is portable | |
785 | and it fully supports classes much like the <tt>%rename</tt> directive. For example: | |
786 | </p> | |
787 | ||
788 | <div class="code"> | |
789 | <pre> | |
790 | %varargs (10, char * = NULL) Foo::bar; | |
791 | ||
792 | class Foo { | |
793 | public: | |
794 | virtual void bar(char *arg, ...); // gets varargs above | |
795 | }; | |
796 | ||
797 | class Spam: public Foo { | |
798 | public: | |
799 | virtual void bar(char *arg, ...); // gets varargs above | |
800 | }; | |
801 | </pre> | |
802 | </div> | |
803 | ||
804 | <p> | |
805 | <tt>%varargs</tt> also works with constructors, operators, and any | |
806 | other C++ programming construct that accepts variable arguments. | |
807 | </p> | |
808 | ||
809 | <p> | |
810 | Doing anything more advanced than this is likely to involve a serious | |
811 | world of pain. In order to use a library like libffi, you will need | |
812 | to know the underlying calling conventions and details of the C++ ABI. For | |
813 | instance, the details of how <tt>this</tt> is passed to member | |
814 | functions as well as any hidden arguments that might be used to pass | |
815 | additional information. These details are implementation specific and | |
816 | may differ between compilers and even different versions of the same | |
817 | compiler. Also, be aware that invoking a member function is further | |
818 | complicated if it is a virtual method. In this case, | |
819 | invocation might require a table lookup to obtain the proper function address | |
820 | (although you might be able to obtain an address by casting a bound | |
821 | pointer to a pointer to function as described in the C++ ARM section | |
822 | 18.3.4). | |
823 | </p> | |
824 | ||
825 | <p> | |
826 | If you do decide to change the underlying action code, be aware that SWIG | |
827 | always places the <tt>this</tt> pointer in <tt>arg1</tt>. Other arguments | |
828 | are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example: | |
829 | </p> | |
830 | ||
831 | <div class="code"> | |
832 | <pre> | |
833 | %feature("action") Foo::bar { | |
834 | ... | |
835 | result = arg1->bar(arg2, arg3, etc.); | |
836 | ... | |
837 | } | |
838 | </pre> | |
839 | </div> | |
840 | ||
841 | <p> | |
842 | Given the potential to shoot yourself in the foot, it is probably easier to reconsider your | |
843 | design or to provide an alternative interface using a helper function than it is to create a | |
844 | fully general wrapper to a varargs C++ member function. | |
845 | </p> | |
846 | ||
847 | <H2><a name="Varargs_nn10"></a>13.9 Discussion</H2> | |
848 | ||
849 | ||
850 | <p> | |
851 | This chapter has provided a number of techniques that can be used to address the problem of variable length | |
852 | argument wrapping. If you care about portability and ease of use, the <tt>%varargs</tt> directive is | |
853 | probably the easiest way to tackle the problem. However, using typemaps, it is possible to do some very advanced | |
854 | kinds of wrapping. | |
855 | </p> | |
856 | ||
857 | <p> | |
858 | One point of discussion concerns the structure of the libffi examples in the previous section. Looking | |
859 | at that code, it is not at all clear that this is the easiest way to solve the problem. However, there | |
860 | are a number of subtle aspects of the solution to consider--mostly concerning the way in which the | |
861 | problem has been decomposed. First, the example is structured in a way that tries to maintain separation | |
862 | between wrapper-specific information and the declaration of the function itself. The idea here is that | |
863 | you might structure your interface like this: | |
864 | </p> | |
865 | ||
866 | <div class="code"> | |
867 | <pre> | |
868 | %typemap(const char *fmt, ...) { | |
869 | ... | |
870 | } | |
871 | %feature("action") traceprintf { | |
872 | ... | |
873 | } | |
874 | ||
875 | /* Include some header file with traceprintf in it */ | |
876 | %include "someheader.h" | |
877 | </pre> | |
878 | </div> | |
879 | ||
880 | <p> | |
881 | Second, careful scrutiny will reveal that the typemaps involving <tt>(...)</tt> have nothing | |
882 | whatsoever to do with the libffi library. In fact, they are generic with respect to the way in which | |
883 | the function is actually called. This decoupling means that it will be much easier to consider | |
884 | other library alternatives for making the function call. For instance, if libffi wasn't supported on a certain | |
885 | platform, you might be able to use something else instead. You could use conditional compilation | |
886 | to control this: | |
887 | </p> | |
888 | ||
889 | <div class="code"> | |
890 | <pre> | |
891 | #ifdef USE_LIBFFI | |
892 | %feature("action") printf { | |
893 | ... | |
894 | } | |
895 | #endif | |
896 | #ifdef USE_OTHERFFI | |
897 | %feature("action") printf { | |
898 | ... | |
899 | } | |
900 | #endif | |
901 | </pre> | |
902 | </div> | |
903 | ||
904 | <p> | |
905 | Finally, even though you might be inclined to just write a hand-written wrapper for varargs functions, | |
906 | the techniques used in the previous section have the advantage of being compatible with all other features | |
907 | of SWIG such as exception handling. | |
908 | </p> | |
909 | ||
910 | <p> | |
911 | As a final word, some C programmers seem to have the assumption that | |
912 | the wrapping of variable length argument functions is an easily solved | |
913 | problem. However, this section has hopefully dispelled some of these | |
914 | myths. All things being equal, you are better off avoiding variable | |
915 | length arguments if you can. If you can't avoid them, please consider | |
916 | some of the simple solutions first. If you can't live with a simple | |
917 | solution, proceed with caution. At the very least, make sure you | |
918 | carefully read the section "A7.3.2 Function Calls" in Kernighan and | |
919 | Ritchie and make sure you fully understand the parameter passing conventions used for varargs. | |
920 | Also, be aware of the platform dependencies and reliability issues that | |
921 | this will introduce. Good luck. | |
922 | </p> | |
923 | ||
924 | </body> | |
925 | </html> |