| 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> |