Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 1 | \input texinfo @c -*-texinfo-*- |
| 2 | @c %**start of header |
| 3 | @setfilename libffi.info |
| 4 | @settitle libffi |
| 5 | @setchapternewpage off |
| 6 | @c %**end of header |
| 7 | |
| 8 | @c Merge the standard indexes into a single one. |
| 9 | @syncodeindex fn cp |
| 10 | @syncodeindex vr cp |
| 11 | @syncodeindex ky cp |
| 12 | @syncodeindex pg cp |
| 13 | @syncodeindex tp cp |
| 14 | |
| 15 | @include version.texi |
| 16 | |
| 17 | @copying |
| 18 | |
| 19 | This manual is for Libffi, a portable foreign-function interface |
| 20 | library. |
| 21 | |
Matthias Klose | 9a65877 | 2010-03-19 19:02:09 +0000 | [diff] [blame] | 22 | Copyright @copyright{} 2008, 2010 Red Hat, Inc. |
Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 23 | |
| 24 | @quotation |
| 25 | Permission is granted to copy, distribute and/or modify this document |
| 26 | under the terms of the GNU General Public License as published by the |
| 27 | Free Software Foundation; either version 2, or (at your option) any |
| 28 | later version. A copy of the license is included in the |
| 29 | section entitled ``GNU General Public License''. |
| 30 | |
| 31 | @end quotation |
| 32 | @end copying |
| 33 | |
| 34 | @dircategory Development |
| 35 | @direntry |
| 36 | * libffi: (libffi). Portable foreign-function interface library. |
| 37 | @end direntry |
| 38 | |
| 39 | @titlepage |
| 40 | @title Libffi |
| 41 | @page |
| 42 | @vskip 0pt plus 1filll |
| 43 | @insertcopying |
| 44 | @end titlepage |
| 45 | |
| 46 | |
| 47 | @ifnottex |
| 48 | @node Top |
| 49 | @top libffi |
| 50 | |
| 51 | @insertcopying |
| 52 | |
| 53 | @menu |
| 54 | * Introduction:: What is libffi? |
| 55 | * Using libffi:: How to use libffi. |
| 56 | * Missing Features:: Things libffi can't do. |
| 57 | * Index:: Index. |
| 58 | @end menu |
| 59 | |
| 60 | @end ifnottex |
| 61 | |
| 62 | |
| 63 | @node Introduction |
| 64 | @chapter What is libffi? |
| 65 | |
| 66 | Compilers for high level languages generate code that follow certain |
| 67 | conventions. These conventions are necessary, in part, for separate |
| 68 | compilation to work. One such convention is the @dfn{calling |
| 69 | convention}. The calling convention is a set of assumptions made by |
| 70 | the compiler about where function arguments will be found on entry to |
| 71 | a function. A calling convention also specifies where the return |
| 72 | value for a function is found. The calling convention is also |
| 73 | sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}. |
| 74 | @cindex calling convention |
| 75 | @cindex ABI |
| 76 | @cindex Application Binary Interface |
| 77 | |
| 78 | Some programs may not know at the time of compilation what arguments |
| 79 | are to be passed to a function. For instance, an interpreter may be |
| 80 | told at run-time about the number and types of arguments used to call |
| 81 | a given function. @samp{Libffi} can be used in such programs to |
| 82 | provide a bridge from the interpreter program to compiled code. |
| 83 | |
| 84 | The @samp{libffi} library provides a portable, high level programming |
| 85 | interface to various calling conventions. This allows a programmer to |
| 86 | call any function specified by a call interface description at run |
| 87 | time. |
| 88 | |
| 89 | @acronym{FFI} stands for Foreign Function Interface. A foreign |
| 90 | function interface is the popular name for the interface that allows |
| 91 | code written in one language to call code written in another language. |
| 92 | The @samp{libffi} library really only provides the lowest, machine |
| 93 | dependent layer of a fully featured foreign function interface. A |
| 94 | layer must exist above @samp{libffi} that handles type conversions for |
| 95 | values passed between the two languages. |
| 96 | @cindex FFI |
| 97 | @cindex Foreign Function Interface |
| 98 | |
| 99 | |
| 100 | @node Using libffi |
| 101 | @chapter Using libffi |
| 102 | |
| 103 | @menu |
| 104 | * The Basics:: The basic libffi API. |
| 105 | * Simple Example:: A simple example. |
| 106 | * Types:: libffi type descriptions. |
| 107 | * Multiple ABIs:: Different passing styles on one platform. |
| 108 | * The Closure API:: Writing a generic function. |
Matthias Klose | 9a65877 | 2010-03-19 19:02:09 +0000 | [diff] [blame] | 109 | * Closure Example:: A closure example. |
Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 110 | @end menu |
| 111 | |
| 112 | |
| 113 | @node The Basics |
| 114 | @section The Basics |
| 115 | |
| 116 | @samp{Libffi} assumes that you have a pointer to the function you wish |
| 117 | to call and that you know the number and types of arguments to pass |
| 118 | it, as well as the return type of the function. |
| 119 | |
| 120 | The first thing you must do is create an @code{ffi_cif} object that |
| 121 | matches the signature of the function you wish to call. This is a |
| 122 | separate step because it is common to make multiple calls using a |
| 123 | single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for |
| 124 | Call InterFace. To prepare a call interface object, use the function |
| 125 | @code{ffi_prep_cif}. |
| 126 | @cindex cif |
| 127 | |
| 128 | @findex ffi_prep_cif |
| 129 | @defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) |
| 130 | This initializes @var{cif} according to the given parameters. |
| 131 | |
| 132 | @var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what |
| 133 | you want. @ref{Multiple ABIs} for more information. |
| 134 | |
| 135 | @var{nargs} is the number of arguments that this function accepts. |
| 136 | @samp{libffi} does not yet handle varargs functions; see @ref{Missing |
| 137 | Features} for more information. |
| 138 | |
| 139 | @var{rtype} is a pointer to an @code{ffi_type} structure that |
| 140 | describes the return type of the function. @xref{Types}. |
| 141 | |
| 142 | @var{argtypes} is a vector of @code{ffi_type} pointers. |
| 143 | @var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0, |
| 144 | this argument is ignored. |
| 145 | |
| 146 | @code{ffi_prep_cif} returns a @code{libffi} status code, of type |
| 147 | @code{ffi_status}. This will be either @code{FFI_OK} if everything |
| 148 | worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type} |
| 149 | objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter |
| 150 | is invalid. |
| 151 | @end defun |
| 152 | |
| 153 | |
| 154 | To call a function using an initialized @code{ffi_cif}, use the |
| 155 | @code{ffi_call} function: |
| 156 | |
| 157 | @findex ffi_call |
| 158 | @defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues}) |
| 159 | This calls the function @var{fn} according to the description given in |
| 160 | @var{cif}. @var{cif} must have already been prepared using |
| 161 | @code{ffi_prep_cif}. |
| 162 | |
| 163 | @var{rvalue} is a pointer to a chunk of memory that will hold the |
| 164 | result of the function call. This must be large enough to hold the |
| 165 | result and must be suitably aligned; it is the caller's responsibility |
| 166 | to ensure this. If @var{cif} declares that the function returns |
| 167 | @code{void} (using @code{ffi_type_void}), then @var{rvalue} is |
| 168 | ignored. If @var{rvalue} is @samp{NULL}, then the return value is |
| 169 | discarded. |
| 170 | |
| 171 | @var{avalues} is a vector of @code{void *} pointers that point to the |
| 172 | memory locations holding the argument values for a call. If @var{cif} |
| 173 | declares that the function has no arguments (i.e., @var{nargs} was 0), |
| 174 | then @var{avalues} is ignored. |
| 175 | @end defun |
| 176 | |
| 177 | |
| 178 | @node Simple Example |
| 179 | @section Simple Example |
| 180 | |
| 181 | Here is a trivial example that calls @code{puts} a few times. |
| 182 | |
| 183 | @example |
| 184 | #include <stdio.h> |
| 185 | #include <ffi.h> |
| 186 | |
| 187 | int main() |
| 188 | @{ |
| 189 | ffi_cif cif; |
| 190 | ffi_type *args[1]; |
| 191 | void *values[1]; |
| 192 | char *s; |
| 193 | int rc; |
| 194 | |
| 195 | /* Initialize the argument info vectors */ |
| 196 | args[0] = &ffi_type_pointer; |
| 197 | values[0] = &s; |
| 198 | |
| 199 | /* Initialize the cif */ |
| 200 | if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, |
| 201 | &ffi_type_uint, args) == FFI_OK) |
| 202 | @{ |
| 203 | s = "Hello World!"; |
| 204 | ffi_call(&cif, puts, &rc, values); |
| 205 | /* rc now holds the result of the call to puts */ |
| 206 | |
| 207 | /* values holds a pointer to the function's arg, so to |
| 208 | call puts() again all we need to do is change the |
| 209 | value of s */ |
| 210 | s = "This is cool!"; |
| 211 | ffi_call(&cif, puts, &rc, values); |
| 212 | @} |
| 213 | |
| 214 | return 0; |
| 215 | @} |
| 216 | @end example |
| 217 | |
| 218 | |
| 219 | @node Types |
| 220 | @section Types |
| 221 | |
| 222 | @menu |
| 223 | * Primitive Types:: Built-in types. |
| 224 | * Structures:: Structure types. |
| 225 | * Type Example:: Structure type example. |
| 226 | @end menu |
| 227 | |
| 228 | @node Primitive Types |
| 229 | @subsection Primitive Types |
| 230 | |
| 231 | @code{Libffi} provides a number of built-in type descriptors that can |
| 232 | be used to describe argument and return types: |
| 233 | |
| 234 | @table @code |
| 235 | @item ffi_type_void |
| 236 | @tindex ffi_type_void |
| 237 | The type @code{void}. This cannot be used for argument types, only |
| 238 | for return values. |
| 239 | |
| 240 | @item ffi_type_uint8 |
| 241 | @tindex ffi_type_uint8 |
| 242 | An unsigned, 8-bit integer type. |
| 243 | |
| 244 | @item ffi_type_sint8 |
| 245 | @tindex ffi_type_sint8 |
| 246 | A signed, 8-bit integer type. |
| 247 | |
| 248 | @item ffi_type_uint16 |
| 249 | @tindex ffi_type_uint16 |
| 250 | An unsigned, 16-bit integer type. |
| 251 | |
| 252 | @item ffi_type_sint16 |
| 253 | @tindex ffi_type_sint16 |
| 254 | A signed, 16-bit integer type. |
| 255 | |
| 256 | @item ffi_type_uint32 |
| 257 | @tindex ffi_type_uint32 |
| 258 | An unsigned, 32-bit integer type. |
| 259 | |
| 260 | @item ffi_type_sint32 |
| 261 | @tindex ffi_type_sint32 |
| 262 | A signed, 32-bit integer type. |
| 263 | |
| 264 | @item ffi_type_uint64 |
| 265 | @tindex ffi_type_uint64 |
| 266 | An unsigned, 64-bit integer type. |
| 267 | |
| 268 | @item ffi_type_sint64 |
| 269 | @tindex ffi_type_sint64 |
| 270 | A signed, 64-bit integer type. |
| 271 | |
| 272 | @item ffi_type_float |
| 273 | @tindex ffi_type_float |
| 274 | The C @code{float} type. |
| 275 | |
| 276 | @item ffi_type_double |
| 277 | @tindex ffi_type_double |
| 278 | The C @code{double} type. |
| 279 | |
| 280 | @item ffi_type_uchar |
| 281 | @tindex ffi_type_uchar |
| 282 | The C @code{unsigned char} type. |
| 283 | |
| 284 | @item ffi_type_schar |
| 285 | @tindex ffi_type_schar |
| 286 | The C @code{signed char} type. (Note that there is not an exact |
| 287 | equivalent to the C @code{char} type in @code{libffi}; ordinarily you |
| 288 | should either use @code{ffi_type_schar} or @code{ffi_type_uchar} |
| 289 | depending on whether @code{char} is signed.) |
| 290 | |
| 291 | @item ffi_type_ushort |
| 292 | @tindex ffi_type_ushort |
| 293 | The C @code{unsigned short} type. |
| 294 | |
| 295 | @item ffi_type_sshort |
| 296 | @tindex ffi_type_sshort |
| 297 | The C @code{short} type. |
| 298 | |
| 299 | @item ffi_type_uint |
| 300 | @tindex ffi_type_uint |
| 301 | The C @code{unsigned int} type. |
| 302 | |
| 303 | @item ffi_type_sint |
| 304 | @tindex ffi_type_sint |
| 305 | The C @code{int} type. |
| 306 | |
| 307 | @item ffi_type_ulong |
| 308 | @tindex ffi_type_ulong |
| 309 | The C @code{unsigned long} type. |
| 310 | |
| 311 | @item ffi_type_slong |
| 312 | @tindex ffi_type_slong |
| 313 | The C @code{long} type. |
| 314 | |
| 315 | @item ffi_type_longdouble |
| 316 | @tindex ffi_type_longdouble |
| 317 | On platforms that have a C @code{long double} type, this is defined. |
| 318 | On other platforms, it is not. |
| 319 | |
| 320 | @item ffi_type_pointer |
| 321 | @tindex ffi_type_pointer |
| 322 | A generic @code{void *} pointer. You should use this for all |
| 323 | pointers, regardless of their real type. |
| 324 | @end table |
| 325 | |
| 326 | Each of these is of type @code{ffi_type}, so you must take the address |
| 327 | when passing to @code{ffi_prep_cif}. |
| 328 | |
| 329 | |
| 330 | @node Structures |
| 331 | @subsection Structures |
| 332 | |
| 333 | Although @samp{libffi} has no special support for unions or |
| 334 | bit-fields, it is perfectly happy passing structures back and forth. |
| 335 | You must first describe the structure to @samp{libffi} by creating a |
| 336 | new @code{ffi_type} object for it. |
| 337 | |
| 338 | @tindex ffi_type |
| 339 | @deftp ffi_type |
| 340 | The @code{ffi_type} has the following members: |
| 341 | @table @code |
| 342 | @item size_t size |
| 343 | This is set by @code{libffi}; you should initialize it to zero. |
| 344 | |
| 345 | @item unsigned short alignment |
| 346 | This is set by @code{libffi}; you should initialize it to zero. |
| 347 | |
| 348 | @item unsigned short type |
| 349 | For a structure, this should be set to @code{FFI_TYPE_STRUCT}. |
| 350 | |
| 351 | @item ffi_type **elements |
| 352 | This is a @samp{NULL}-terminated array of pointers to @code{ffi_type} |
| 353 | objects. There is one element per field of the struct. |
| 354 | @end table |
| 355 | @end deftp |
| 356 | |
| 357 | |
| 358 | @node Type Example |
| 359 | @subsection Type Example |
| 360 | |
| 361 | The following example initializes a @code{ffi_type} object |
| 362 | representing the @code{tm} struct from Linux's @file{time.h}. |
| 363 | |
| 364 | Here is how the struct is defined: |
| 365 | |
| 366 | @example |
| 367 | struct tm @{ |
| 368 | int tm_sec; |
| 369 | int tm_min; |
| 370 | int tm_hour; |
| 371 | int tm_mday; |
| 372 | int tm_mon; |
| 373 | int tm_year; |
| 374 | int tm_wday; |
| 375 | int tm_yday; |
| 376 | int tm_isdst; |
| 377 | /* Those are for future use. */ |
| 378 | long int __tm_gmtoff__; |
| 379 | __const char *__tm_zone__; |
| 380 | @}; |
| 381 | @end example |
| 382 | |
| 383 | Here is the corresponding code to describe this struct to |
| 384 | @code{libffi}: |
| 385 | |
| 386 | @example |
| 387 | @{ |
| 388 | ffi_type tm_type; |
| 389 | ffi_type *tm_type_elements[12]; |
| 390 | int i; |
| 391 | |
| 392 | tm_type.size = tm_type.alignment = 0; |
| 393 | tm_type.elements = &tm_type_elements; |
| 394 | |
| 395 | for (i = 0; i < 9; i++) |
| 396 | tm_type_elements[i] = &ffi_type_sint; |
| 397 | |
| 398 | tm_type_elements[9] = &ffi_type_slong; |
| 399 | tm_type_elements[10] = &ffi_type_pointer; |
| 400 | tm_type_elements[11] = NULL; |
| 401 | |
| 402 | /* tm_type can now be used to represent tm argument types and |
| 403 | return types for ffi_prep_cif() */ |
| 404 | @} |
| 405 | @end example |
| 406 | |
| 407 | |
| 408 | @node Multiple ABIs |
| 409 | @section Multiple ABIs |
| 410 | |
| 411 | A given platform may provide multiple different ABIs at once. For |
| 412 | instance, the x86 platform has both @samp{stdcall} and @samp{fastcall} |
| 413 | functions. |
| 414 | |
| 415 | @code{libffi} provides some support for this. However, this is |
| 416 | necessarily platform-specific. |
| 417 | |
| 418 | @c FIXME: document the platforms |
| 419 | |
| 420 | @node The Closure API |
| 421 | @section The Closure API |
| 422 | |
| 423 | @code{libffi} also provides a way to write a generic function -- a |
| 424 | function that can accept and decode any combination of arguments. |
| 425 | This can be useful when writing an interpreter, or to provide wrappers |
| 426 | for arbitrary functions. |
| 427 | |
| 428 | This facility is called the @dfn{closure API}. Closures are not |
| 429 | supported on all platforms; you can check the @code{FFI_CLOSURES} |
| 430 | define to determine whether they are supported on the current |
| 431 | platform. |
| 432 | @cindex closures |
| 433 | @cindex closure API |
| 434 | @findex FFI_CLOSURES |
| 435 | |
| 436 | Because closures work by assembling a tiny function at runtime, they |
| 437 | require special allocation on platforms that have a non-executable |
| 438 | heap. Memory management for closures is handled by a pair of |
| 439 | functions: |
| 440 | |
| 441 | @findex ffi_closure_alloca |
| 442 | @defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code}) |
| 443 | Allocate a chunk of memory holding @var{size} bytes. This returns a |
| 444 | pointer to the writable address, and sets *@var{code} to the |
| 445 | corresponding executable address. |
| 446 | |
| 447 | @var{size} should be sufficient to hold a @code{ffi_closure} object. |
| 448 | @end defun |
| 449 | |
| 450 | @findex ffi_closure_free |
| 451 | @defun void ffi_closure_free (void *@var{writable}) |
| 452 | Free memory allocated using @code{ffi_closure_alloc}. The argument is |
| 453 | the writable address that was returned. |
| 454 | @end defun |
| 455 | |
| 456 | |
| 457 | Once you have allocated the memory for a closure, you must construct a |
| 458 | @code{ffi_cif} describing the function call. Finally you can prepare |
| 459 | the closure function: |
| 460 | |
| 461 | @findex ffi_prep_closure_loc |
| 462 | @defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc}) |
| 463 | Prepare a closure function. |
| 464 | |
| 465 | @var{closure} is the address of a @code{ffi_closure} object; this is |
| 466 | the writable address returned by @code{ffi_closure_alloc}. |
| 467 | |
| 468 | @var{cif} is the @code{ffi_cif} describing the function parameters. |
| 469 | |
| 470 | @var{user_data} is an arbitrary datum that is passed, uninterpreted, |
| 471 | to your closure function. |
| 472 | |
| 473 | @var{codeloc} is the executable address returned by |
| 474 | @code{ffi_closure_alloc}. |
| 475 | |
| 476 | @var{fun} is the function which will be called when the closure is |
| 477 | invoked. It is called with the arguments: |
| 478 | @table @var |
| 479 | @item cif |
| 480 | The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}. |
| 481 | |
| 482 | @item ret |
| 483 | A pointer to the memory used for the function's return value. |
| 484 | @var{fun} must fill this, unless the function is declared as returning |
| 485 | @code{void}. |
| 486 | @c FIXME: is this NULL for void-returning functions? |
| 487 | |
| 488 | @item args |
| 489 | A vector of pointers to memory holding the arguments to the function. |
| 490 | |
| 491 | @item user_data |
| 492 | The same @var{user_data} that was passed to |
| 493 | @code{ffi_prep_closure_loc}. |
| 494 | @end table |
| 495 | |
| 496 | @code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything |
| 497 | went ok, and something else on error. |
| 498 | @c FIXME: what? |
| 499 | |
| 500 | After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc} |
| 501 | to the appropriate pointer-to-function type. |
| 502 | @end defun |
| 503 | |
Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 504 | You may see old code referring to @code{ffi_prep_closure}. This |
| 505 | function is deprecated, as it cannot handle the need for separate |
| 506 | writable and executable addresses. |
| 507 | |
Matthias Klose | 9a65877 | 2010-03-19 19:02:09 +0000 | [diff] [blame] | 508 | @node Closure Example |
| 509 | @section Closure Example |
| 510 | |
| 511 | A trivial example that creates a new @code{puts} by binding |
| 512 | @code{fputs} with @code{stdin}. |
| 513 | |
| 514 | @example |
| 515 | #include <stdio.h> |
| 516 | #include <ffi.h> |
| 517 | |
| 518 | /* Acts like puts with the file given at time of enclosure. */ |
| 519 | void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], |
| 520 | FILE *stream) |
| 521 | @{ |
| 522 | *ret = fputs(*(char **)args[0], stream); |
| 523 | @} |
| 524 | |
| 525 | int main() |
| 526 | @{ |
| 527 | ffi_cif cif; |
| 528 | ffi_type *args[1]; |
| 529 | ffi_closure *closure; |
| 530 | |
| 531 | int (*bound_puts)(char *); |
| 532 | int rc; |
| 533 | |
| 534 | /* Allocate closure and bound_puts */ |
| 535 | closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); |
| 536 | |
| 537 | if (closure) |
| 538 | @{ |
| 539 | /* Initialize the argument info vectors */ |
| 540 | args[0] = &ffi_type_pointer; |
| 541 | |
| 542 | /* Initialize the cif */ |
| 543 | if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, |
| 544 | &ffi_type_uint, args) == FFI_OK) |
| 545 | @{ |
| 546 | /* Initialize the closure, setting stream to stdout */ |
| 547 | if (ffi_prep_closure_loc(closure, &cif, puts_binding, |
| 548 | stdout, bound_puts) == FFI_OK) |
| 549 | @{ |
| 550 | rc = bound_puts("Hello World!"); |
| 551 | /* rc now holds the result of the call to fputs */ |
| 552 | @} |
| 553 | @} |
| 554 | @} |
| 555 | |
| 556 | /* Deallocate both closure, and bound_puts */ |
| 557 | ffi_closure_free(closure); |
| 558 | |
| 559 | return 0; |
| 560 | @} |
| 561 | |
| 562 | @end example |
| 563 | |
Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 564 | |
| 565 | @node Missing Features |
| 566 | @chapter Missing Features |
| 567 | |
| 568 | @code{libffi} is missing a few features. We welcome patches to add |
| 569 | support for these. |
| 570 | |
| 571 | @itemize @bullet |
| 572 | @item |
| 573 | There is no support for calling varargs functions. This may work on |
| 574 | some platforms, depending on how the ABI is defined, but it is not |
| 575 | reliable. |
| 576 | |
| 577 | @item |
| 578 | There is no support for bit fields in structures. |
| 579 | |
| 580 | @item |
| 581 | The closure API is |
| 582 | |
Matthias Klose | 9a65877 | 2010-03-19 19:02:09 +0000 | [diff] [blame] | 583 | @c FIXME: ... |
| 584 | |
Matthias Klose | a834975 | 2010-03-15 13:25:28 +0000 | [diff] [blame] | 585 | @item |
| 586 | The ``raw'' API is undocumented. |
| 587 | @c argument promotion? |
| 588 | @c unions? |
| 589 | @c anything else? |
| 590 | @end itemize |
| 591 | |
| 592 | |
| 593 | @node Index |
| 594 | @unnumbered Index |
| 595 | |
| 596 | @printindex cp |
| 597 | |
| 598 | @bye |