summaryrefslogtreecommitdiff
path: root/ext/ffi_c/libffi/doc/libffi.info
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi_c/libffi/doc/libffi.info')
-rw-r--r--ext/ffi_c/libffi/doc/libffi.info502
1 files changed, 337 insertions, 165 deletions
diff --git a/ext/ffi_c/libffi/doc/libffi.info b/ext/ffi_c/libffi/doc/libffi.info
index 449320c..c4d0f0c 100644
--- a/ext/ffi_c/libffi/doc/libffi.info
+++ b/ext/ffi_c/libffi/doc/libffi.info
@@ -1,17 +1,15 @@
-This is ../libffi/doc/libffi.info, produced by makeinfo version 4.13
-from ../libffi/doc/libffi.texi.
+This is libffi.info, produced by makeinfo version 5.1 from libffi.texi.
This manual is for Libffi, a portable foreign-function interface
library.
- Copyright (C) 2008, 2010 Red Hat, Inc.
+ Copyright (C) 2008, 2010, 2011 Red Hat, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or
- (at your option) any later version. A copy of the license is
- included in the section entitled "GNU General Public License".
-
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version. A copy of the license is included
+ in the section entitled "GNU General Public License".
INFO-DIR-SECTION Development
START-INFO-DIR-ENTRY
@@ -27,14 +25,13 @@ libffi
This manual is for Libffi, a portable foreign-function interface
library.
- Copyright (C) 2008, 2010 Red Hat, Inc.
+ Copyright (C) 2008, 2010, 2011 Red Hat, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or
- (at your option) any later version. A copy of the license is
- included in the section entitled "GNU General Public License".
-
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version. A copy of the license is included
+ in the section entitled "GNU General Public License".
* Menu:
@@ -56,25 +53,25 @@ The calling convention is a set of assumptions made by the compiler
about where function arguments will be found on entry to a function. A
calling convention also specifies where the return value for a function
is found. The calling convention is also sometimes called the "ABI" or
-"Application Binary Interface".
+"Application Binary Interface".
Some programs may not know at the time of compilation what arguments
are to be passed to a function. For instance, an interpreter may be
told at run-time about the number and types of arguments used to call a
-given function. `Libffi' can be used in such programs to provide a
+given function. 'Libffi' can be used in such programs to provide a
bridge from the interpreter program to compiled code.
- The `libffi' library provides a portable, high level programming
+ The 'libffi' library provides a portable, high level programming
interface to various calling conventions. This allows a programmer to
call any function specified by a call interface description at run time.
FFI stands for Foreign Function Interface. A foreign function
-interface is the popular name for the interface that allows code
-written in one language to call code written in another language. The
-`libffi' library really only provides the lowest, machine dependent
-layer of a fully featured foreign function interface. A layer must
-exist above `libffi' that handles type conversions for values passed
-between the two languages.
+interface is the popular name for the interface that allows code written
+in one language to call code written in another language. The 'libffi'
+library really only provides the lowest, machine dependent layer of a
+fully featured foreign function interface. A layer must exist above
+'libffi' that handles type conversions for values passed between the two
+languages.

File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top
@@ -97,54 +94,75 @@ File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi
2.1 The Basics
==============
-`Libffi' assumes that you have a pointer to the function you wish to
+'Libffi' assumes that you have a pointer to the function you wish to
call and that you know the number and types of arguments to pass it, as
well as the return type of the function.
- The first thing you must do is create an `ffi_cif' object that
+ The first thing you must do is create an 'ffi_cif' object that
matches the signature of the function you wish to call. This is a
-separate step because it is common to make multiple calls using a
-single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace.
-To prepare a call interface object, use the function `ffi_prep_cif'.
+separate step because it is common to make multiple calls using a single
+'ffi_cif'. The "cif" in 'ffi_cif' stands for Call InterFace. To
+prepare a call interface object, use the function 'ffi_prep_cif'.
-- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI,
unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES)
This initializes CIF according to the given parameters.
- ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you
- want. *note Multiple ABIs:: for more information.
+ ABI is the ABI to use; normally 'FFI_DEFAULT_ABI' is what you want.
+ *note Multiple ABIs:: for more information.
NARGS is the number of arguments that this function accepts.
- `libffi' does not yet handle varargs functions; see *note Missing
- Features:: for more information.
- RTYPE is a pointer to an `ffi_type' structure that describes the
+ RTYPE is a pointer to an 'ffi_type' structure that describes the
return type of the function. *Note Types::.
- ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have
+ ARGTYPES is a vector of 'ffi_type' pointers. ARGTYPES must have
NARGS elements. If NARGS is 0, this argument is ignored.
- `ffi_prep_cif' returns a `libffi' status code, of type
- `ffi_status'. This will be either `FFI_OK' if everything worked
- properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is
- incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid.
+ 'ffi_prep_cif' returns a 'libffi' status code, of type
+ 'ffi_status'. This will be either 'FFI_OK' if everything worked
+ properly; 'FFI_BAD_TYPEDEF' if one of the 'ffi_type' objects is
+ incorrect; or 'FFI_BAD_ABI' if the ABI parameter is invalid.
+
+ If the function being called is variadic (varargs) then
+'ffi_prep_cif_var' must be used instead of 'ffi_prep_cif'.
+
+ -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi varabi,
+ unsigned int NFIXEDARGS, unsigned int varntotalargs, ffi_type
+ *RTYPE, ffi_type **ARGTYPES)
+ This initializes CIF according to the given parameters for a call
+ to a variadic function. In general it's operation is the same as
+ for 'ffi_prep_cif' except that:
+
+ NFIXEDARGS is the number of fixed arguments, prior to any variadic
+ arguments. It must be greater than zero.
+
+ NTOTALARGS the total number of arguments, including variadic and
+ fixed arguments.
+
+ Note that, different cif's must be prepped for calls to the same
+ function when different numbers of arguments are passed.
- To call a function using an initialized `ffi_cif', use the
-`ffi_call' function:
+ Also note that a call to 'ffi_prep_cif_var' with
+ NFIXEDARGS=NOTOTALARGS is NOT equivalent to a call to
+ 'ffi_prep_cif'.
+
+ To call a function using an initialized 'ffi_cif', use the 'ffi_call'
+function:
-- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void
**AVALUES)
This calls the function FN according to the description given in
- CIF. CIF must have already been prepared using `ffi_prep_cif'.
+ CIF. CIF must have already been prepared using 'ffi_prep_cif'.
RVALUE is a pointer to a chunk of memory that will hold the result
of the function call. This must be large enough to hold the
- result and must be suitably aligned; it is the caller's
+ result, no smaller than the system register size (generally 32 or
+ 64 bits), and must be suitably aligned; it is the caller's
responsibility to ensure this. If CIF declares that the function
- returns `void' (using `ffi_type_void'), then RVALUE is ignored.
- If RVALUE is `NULL', then the return value is discarded.
+ returns 'void' (using 'ffi_type_void'), then RVALUE is ignored.
- AVALUES is a vector of `void *' pointers that point to the memory
+ AVALUES is a vector of 'void *' pointers that point to the memory
locations holding the argument values for a call. If CIF declares
that the function has no arguments (i.e., NARGS was 0), then
AVALUES is ignored. Note that argument values may be modified by
@@ -157,7 +175,7 @@ File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up:
2.2 Simple Example
==================
-Here is a trivial example that calls `puts' a few times.
+Here is a trivial example that calls 'puts' a few times.
#include <stdio.h>
#include <ffi.h>
@@ -168,7 +186,7 @@ Here is a trivial example that calls `puts' a few times.
ffi_type *args[1];
void *values[1];
char *s;
- int rc;
+ ffi_arg rc;
/* Initialize the argument info vectors */
args[0] = &ffi_type_pointer;
@@ -176,7 +194,7 @@ Here is a trivial example that calls `puts' a few times.
/* Initialize the cif */
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
- &ffi_type_uint, args) == FFI_OK)
+ &ffi_type_sint, args) == FFI_OK)
{
s = "Hello World!";
ffi_call(&cif, puts, &rc, values);
@@ -203,6 +221,8 @@ File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, U
* Primitive Types:: Built-in types.
* Structures:: Structure types.
* Type Example:: Structure type example.
+* Complex:: Complex types.
+* Complex Type Example:: Complex type example.

File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types
@@ -210,80 +230,91 @@ File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types
2.3.1 Primitive Types
---------------------
-`Libffi' provides a number of built-in type descriptors that can be
-used to describe argument and return types:
+'Libffi' provides a number of built-in type descriptors that can be used
+to describe argument and return types:
-`ffi_type_void'
- The type `void'. This cannot be used for argument types, only for
+'ffi_type_void'
+ The type 'void'. This cannot be used for argument types, only for
return values.
-`ffi_type_uint8'
+'ffi_type_uint8'
An unsigned, 8-bit integer type.
-`ffi_type_sint8'
+'ffi_type_sint8'
A signed, 8-bit integer type.
-`ffi_type_uint16'
+'ffi_type_uint16'
An unsigned, 16-bit integer type.
-`ffi_type_sint16'
+'ffi_type_sint16'
A signed, 16-bit integer type.
-`ffi_type_uint32'
+'ffi_type_uint32'
An unsigned, 32-bit integer type.
-`ffi_type_sint32'
+'ffi_type_sint32'
A signed, 32-bit integer type.
-`ffi_type_uint64'
+'ffi_type_uint64'
An unsigned, 64-bit integer type.
-`ffi_type_sint64'
+'ffi_type_sint64'
A signed, 64-bit integer type.
-`ffi_type_float'
- The C `float' type.
+'ffi_type_float'
+ The C 'float' type.
-`ffi_type_double'
- The C `double' type.
+'ffi_type_double'
+ The C 'double' type.
-`ffi_type_uchar'
- The C `unsigned char' type.
+'ffi_type_uchar'
+ The C 'unsigned char' type.
-`ffi_type_schar'
- The C `signed char' type. (Note that there is not an exact
- equivalent to the C `char' type in `libffi'; ordinarily you should
- either use `ffi_type_schar' or `ffi_type_uchar' depending on
- whether `char' is signed.)
+'ffi_type_schar'
+ The C 'signed char' type. (Note that there is not an exact
+ equivalent to the C 'char' type in 'libffi'; ordinarily you should
+ either use 'ffi_type_schar' or 'ffi_type_uchar' depending on
+ whether 'char' is signed.)
-`ffi_type_ushort'
- The C `unsigned short' type.
+'ffi_type_ushort'
+ The C 'unsigned short' type.
-`ffi_type_sshort'
- The C `short' type.
+'ffi_type_sshort'
+ The C 'short' type.
-`ffi_type_uint'
- The C `unsigned int' type.
+'ffi_type_uint'
+ The C 'unsigned int' type.
-`ffi_type_sint'
- The C `int' type.
+'ffi_type_sint'
+ The C 'int' type.
-`ffi_type_ulong'
- The C `unsigned long' type.
+'ffi_type_ulong'
+ The C 'unsigned long' type.
-`ffi_type_slong'
- The C `long' type.
+'ffi_type_slong'
+ The C 'long' type.
-`ffi_type_longdouble'
- On platforms that have a C `long double' type, this is defined.
- On other platforms, it is not.
+'ffi_type_longdouble'
+ On platforms that have a C 'long double' type, this is defined. On
+ other platforms, it is not.
-`ffi_type_pointer'
- A generic `void *' pointer. You should use this for all pointers,
+'ffi_type_pointer'
+ A generic 'void *' pointer. You should use this for all pointers,
regardless of their real type.
- Each of these is of type `ffi_type', so you must take the address
-when passing to `ffi_prep_cif'.
+'ffi_type_complex_float'
+ The C '_Complex float' type.
+
+'ffi_type_complex_double'
+ The C '_Complex double' type.
+
+'ffi_type_complex_longdouble'
+ The C '_Complex long double' type. On platforms that have a C
+ 'long double' type, this is defined. On other platforms, it is
+ not.
+
+ Each of these is of type 'ffi_type', so you must take the address
+when passing to 'ffi_prep_cif'.

File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types
@@ -291,34 +322,34 @@ File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Type
2.3.2 Structures
----------------
-Although `libffi' has no special support for unions or bit-fields, it
-is perfectly happy passing structures back and forth. You must first
-describe the structure to `libffi' by creating a new `ffi_type' object
+Although 'libffi' has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to 'libffi' by creating a new 'ffi_type' object
for it.
- -- ffi_type:
- The `ffi_type' has the following members:
- `size_t size'
- This is set by `libffi'; you should initialize it to zero.
+ -- Data type: ffi_type
+ The 'ffi_type' has the following members:
+ 'size_t size'
+ This is set by 'libffi'; you should initialize it to zero.
- `unsigned short alignment'
- This is set by `libffi'; you should initialize it to zero.
+ 'unsigned short alignment'
+ This is set by 'libffi'; you should initialize it to zero.
- `unsigned short type'
- For a structure, this should be set to `FFI_TYPE_STRUCT'.
+ 'unsigned short type'
+ For a structure, this should be set to 'FFI_TYPE_STRUCT'.
- `ffi_type **elements'
- This is a `NULL'-terminated array of pointers to `ffi_type'
+ 'ffi_type **elements'
+ This is a 'NULL'-terminated array of pointers to 'ffi_type'
objects. There is one element per field of the struct.

-File: libffi.info, Node: Type Example, Prev: Structures, Up: Types
+File: libffi.info, Node: Type Example, Next: Complex, Prev: Structures, Up: Types
2.3.3 Type Example
------------------
-The following example initializes a `ffi_type' object representing the
-`tm' struct from Linux's `time.h'.
+The following example initializes a 'ffi_type' object representing the
+'tm' struct from Linux's 'time.h'.
Here is how the struct is defined:
@@ -337,7 +368,7 @@ The following example initializes a `ffi_type' object representing the
__const char *__tm_zone__;
};
- Here is the corresponding code to describe this struct to `libffi':
+ Here is the corresponding code to describe this struct to 'libffi':
{
ffi_type tm_type;
@@ -345,6 +376,7 @@ The following example initializes a `ffi_type' object representing the
int i;
tm_type.size = tm_type.alignment = 0;
+ tm_type.type = FFI_TYPE_STRUCT;
tm_type.elements = &tm_type_elements;
for (i = 0; i < 9; i++)
@@ -359,15 +391,142 @@ The following example initializes a `ffi_type' object representing the
}

+File: libffi.info, Node: Complex, Next: Complex Type Example, Prev: Type Example, Up: Types
+
+2.3.4 Complex Types
+-------------------
+
+'libffi' supports the complex types defined by the C99 standard
+('_Complex float', '_Complex double' and '_Complex long double' with the
+built-in type descriptors 'ffi_type_complex_float',
+'ffi_type_complex_double' and 'ffi_type_complex_longdouble'.
+
+ Custom complex types like '_Complex int' can also be used. An
+'ffi_type' object has to be defined to describe the complex type to
+'libffi'.
+
+ -- Data type: ffi_type
+ 'size_t size'
+ This must be manually set to the size of the complex type.
+
+ 'unsigned short alignment'
+ This must be manually set to the alignment of the complex
+ type.
+
+ 'unsigned short type'
+ For a complex type, this must be set to 'FFI_TYPE_COMPLEX'.
+
+ 'ffi_type **elements'
+
+ This is a 'NULL'-terminated array of pointers to 'ffi_type'
+ objects. The first element is set to the 'ffi_type' of the
+ complex's base type. The second element must be set to
+ 'NULL'.
+
+ The section *note Complex Type Example:: shows a way to determine the
+'size' and 'alignment' members in a platform independent way.
+
+ For platforms that have no complex support in 'libffi' yet, the
+functions 'ffi_prep_cif' and 'ffi_prep_args' abort the program if they
+encounter a complex type.
+
+
+File: libffi.info, Node: Complex Type Example, Prev: Complex, Up: Types
+
+2.3.5 Complex Type Example
+--------------------------
+
+This example demonstrates how to use complex types:
+
+ #include <stdio.h>
+ #include <ffi.h>
+ #include <complex.h>
+
+ void complex_fn(_Complex float cf,
+ _Complex double cd,
+ _Complex long double cld)
+ {
+ printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
+ (float)creal (cf), (float)cimag (cf),
+ (float)creal (cd), (float)cimag (cd),
+ (float)creal (cld), (float)cimag (cld));
+ }
+
+ int main()
+ {
+ ffi_cif cif;
+ ffi_type *args[3];
+ void *values[3];
+ _Complex float cf;
+ _Complex double cd;
+ _Complex long double cld;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_complex_float;
+ args[1] = &ffi_type_complex_double;
+ args[2] = &ffi_type_complex_longdouble;
+ values[0] = &cf;
+ values[1] = &cd;
+ values[2] = &cld;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_void, args) == FFI_OK)
+ {
+ cf = 1.0 + 20.0 * I;
+ cd = 300.0 + 4000.0 * I;
+ cld = 50000.0 + 600000.0 * I;
+ /* Call the function */
+ ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
+ }
+
+ return 0;
+ }
+
+ This is an example for defining a custom complex type descriptor for
+compilers that support them:
+
+ /*
+ * This macro can be used to define new complex type descriptors
+ * in a platform independent way.
+ *
+ * name: Name of the new descriptor is ffi_type_complex_<name>.
+ * type: The C base type of the complex type.
+ */
+ #define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
+ static ffi_type *ffi_elements_complex_##name [2] = { \
+ (ffi_type *)(&ffitype), NULL \
+ }; \
+ struct struct_align_complex_##name { \
+ char c; \
+ _Complex type x; \
+ }; \
+ ffi_type ffi_type_complex_##name = { \
+ sizeof(_Complex type), \
+ offsetof(struct struct_align_complex_##name, x), \
+ FFI_TYPE_COMPLEX, \
+ (ffi_type **)ffi_elements_complex_##name \
+ }
+
+ /* Define new complex type descriptors using the macro: */
+ /* ffi_type_complex_sint */
+ FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
+ /* ffi_type_complex_uchar */
+ FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
+
+ The new type descriptors can then be used like one of the built-in
+type descriptors in the previous example.
+
+
File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, Up: Using libffi
2.4 Multiple ABIs
=================
A given platform may provide multiple different ABIs at once. For
-instance, the x86 platform has both `stdcall' and `fastcall' functions.
+instance, the x86 platform has both 'stdcall' and 'fastcall' functions.
- `libffi' provides some support for this. However, this is
+ 'libffi' provides some support for this. However, this is
necessarily platform-specific.

@@ -376,32 +535,32 @@ File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multip
2.5 The Closure API
===================
-`libffi' also provides a way to write a generic function - a function
+'libffi' also provides a way to write a generic function - a function
that can accept and decode any combination of arguments. This can be
-useful when writing an interpreter, or to provide wrappers for
-arbitrary functions.
+useful when writing an interpreter, or to provide wrappers for arbitrary
+functions.
- This facility is called the "closure API". Closures are not
-supported on all platforms; you can check the `FFI_CLOSURES' define to
-determine whether they are supported on the current platform.
+ This facility is called the "closure API". Closures are not supported
+on all platforms; you can check the 'FFI_CLOSURES' define to determine
+whether they are supported on the current platform.
Because closures work by assembling a tiny function at runtime, they
-require special allocation on platforms that have a non-executable
-heap. Memory management for closures is handled by a pair of functions:
+require special allocation on platforms that have a non-executable heap.
+Memory management for closures is handled by a pair of functions:
-- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE)
Allocate a chunk of memory holding SIZE bytes. This returns a
pointer to the writable address, and sets *CODE to the
corresponding executable address.
- SIZE should be sufficient to hold a `ffi_closure' object.
+ SIZE should be sufficient to hold a 'ffi_closure' object.
-- Function: void ffi_closure_free (void *WRITABLE)
- Free memory allocated using `ffi_closure_alloc'. The argument is
+ Free memory allocated using 'ffi_closure_alloc'. The argument is
the writable address that was returned.
Once you have allocated the memory for a closure, you must construct
-a `ffi_cif' describing the function call. Finally you can prepare the
+a 'ffi_cif' describing the function call. Finally you can prepare the
closure function:
-- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE,
@@ -409,40 +568,40 @@ closure function:
**ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC)
Prepare a closure function.
- CLOSURE is the address of a `ffi_closure' object; this is the
- writable address returned by `ffi_closure_alloc'.
+ CLOSURE is the address of a 'ffi_closure' object; this is the
+ writable address returned by 'ffi_closure_alloc'.
- CIF is the `ffi_cif' describing the function parameters.
+ CIF is the 'ffi_cif' describing the function parameters.
USER_DATA is an arbitrary datum that is passed, uninterpreted, to
your closure function.
- CODELOC is the executable address returned by `ffi_closure_alloc'.
+ CODELOC is the executable address returned by 'ffi_closure_alloc'.
FUN is the function which will be called when the closure is
invoked. It is called with the arguments:
- CIF
- The `ffi_cif' passed to `ffi_prep_closure_loc'.
+ CIF
+ The 'ffi_cif' passed to 'ffi_prep_closure_loc'.
- RET
+ RET
A pointer to the memory used for the function's return value.
FUN must fill this, unless the function is declared as
- returning `void'.
+ returning 'void'.
- ARGS
+ ARGS
A vector of pointers to memory holding the arguments to the
function.
- USER_DATA
- The same USER_DATA that was passed to `ffi_prep_closure_loc'.
+ USER_DATA
+ The same USER_DATA that was passed to 'ffi_prep_closure_loc'.
- `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok,
+ 'ffi_prep_closure_loc' will return 'FFI_OK' if everything went ok,
and something else on error.
- After calling `ffi_prep_closure_loc', you can cast CODELOC to the
+ After calling 'ffi_prep_closure_loc', you can cast CODELOC to the
appropriate pointer-to-function type.
- You may see old code referring to `ffi_prep_closure'. This function
+ You may see old code referring to 'ffi_prep_closure'. This function
is deprecated, as it cannot handle the need for separate writable and
executable addresses.
@@ -452,26 +611,28 @@ File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using li
2.6 Closure Example
===================
-A trivial example that creates a new `puts' by binding `fputs' with
-`stdin'.
+A trivial example that creates a new 'puts' by binding 'fputs' with
+'stdout'.
#include <stdio.h>
#include <ffi.h>
/* Acts like puts with the file given at time of enclosure. */
- void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
- FILE *stream)
+ void puts_binding(ffi_cif *cif, void *ret, void* args[],
+ void *stream)
{
- *ret = fputs(*(char **)args[0], stream);
+ *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
}
+ typedef int (*puts_t)(char *);
+
int main()
{
ffi_cif cif;
ffi_type *args[1];
ffi_closure *closure;
- int (*bound_puts)(char *);
+ void *bound_puts;
int rc;
/* Allocate closure and bound_puts */
@@ -484,13 +645,13 @@ A trivial example that creates a new `puts' by binding `fputs' with
/* Initialize the cif */
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
- &ffi_type_uint, args) == FFI_OK)
+ &ffi_type_sint, args) == FFI_OK)
{
/* Initialize the closure, setting stream to stdout */
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
stdout, bound_puts) == FFI_OK)
{
- rc = bound_puts("Hello World!");
+ rc = ((puts_t)bound_puts)("Hello World!");
/* rc now holds the result of the call to fputs */
}
}
@@ -508,12 +669,10 @@ File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi,
3 Missing Features
******************
-`libffi' is missing a few features. We welcome patches to add support
+'libffi' is missing a few features. We welcome patches to add support
for these.
- * There is no support for calling varargs functions. This may work
- on some platforms, depending on how the ABI is defined, but it is
- not reliable.
+ * Variadic closures.
* There is no support for bit fields in structures.
@@ -521,6 +680,9 @@ for these.
* The "raw" API is undocumented.
+ Note that variadic support is very new and tested on a relatively
+small number of platforms.
+

File: libffi.info, Node: Index, Prev: Missing Features, Up: Top
@@ -530,7 +692,6 @@ Index
* Menu:
-* : Structures. (line 12)
* ABI: Introduction. (line 13)
* Application Binary Interface: Introduction. (line 13)
* calling convention: Introduction. (line 13)
@@ -538,15 +699,23 @@ Index
* closure API: The Closure API. (line 13)
* closures: The Closure API. (line 13)
* FFI: Introduction. (line 31)
-* ffi_call: The Basics. (line 41)
+* ffi_call: The Basics. (line 62)
+* FFI_CLOSURES: The Closure API. (line 13)
* ffi_closure_alloc: The Closure API. (line 19)
* ffi_closure_free: The Closure API. (line 26)
-* FFI_CLOSURES: The Closure API. (line 13)
* ffi_prep_cif: The Basics. (line 16)
+* ffi_prep_cif_var: The Basics. (line 39)
* ffi_prep_closure_loc: The Closure API. (line 34)
-* ffi_status <1>: The Closure API. (line 37)
-* ffi_status: The Basics. (line 18)
+* ffi_status: The Basics. (line 16)
+* ffi_status <1>: The Basics. (line 39)
+* ffi_status <2>: The Closure API. (line 34)
* ffi_type: Structures. (line 11)
+* ffi_type <1>: Structures. (line 11)
+* ffi_type <2>: Complex. (line 15)
+* ffi_type <3>: Complex. (line 15)
+* ffi_type_complex_double: Primitive Types. (line 82)
+* ffi_type_complex_float: Primitive Types. (line 79)
+* ffi_type_complex_longdouble: Primitive Types. (line 85)
* ffi_type_double: Primitive Types. (line 41)
* ffi_type_float: Primitive Types. (line 38)
* ffi_type_longdouble: Primitive Types. (line 71)
@@ -569,25 +738,28 @@ Index
* ffi_type_ushort: Primitive Types. (line 53)
* ffi_type_void: Primitive Types. (line 10)
* Foreign Function Interface: Introduction. (line 31)
-* void <1>: The Closure API. (line 20)
-* void: The Basics. (line 43)
+* void: The Basics. (line 62)
+* void <1>: The Closure API. (line 19)
+* void <2>: The Closure API. (line 26)

Tag Table:
-Node: Top706
-Node: Introduction1448
-Node: Using libffi3084
-Node: The Basics3570
-Node: Simple Example6356
-Node: Types7383
-Node: Primitive Types7666
-Node: Structures9486
-Node: Type Example10346
-Node: Multiple ABIs11569
-Node: The Closure API11940
-Node: Closure Example14884
-Node: Missing Features16443
-Node: Index16936
+Node: Top682
+Node: Introduction1429
+Node: Using libffi3061
+Node: The Basics3547
+Node: Simple Example7198
+Node: Types8229
+Node: Primitive Types8613
+Node: Structures10734
+Node: Type Example11608
+Node: Complex12890
+Node: Complex Type Example14308
+Node: Multiple ABIs17360
+Node: The Closure API17731
+Node: Closure Example20675
+Node: Missing Features22284
+Node: Index22737

End Tag Table