| 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, 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". |
| |
| INFO-DIR-SECTION Development |
| START-INFO-DIR-ENTRY |
| * libffi: (libffi). Portable foreign-function interface library. |
| END-INFO-DIR-ENTRY |
| |
| |
| File: libffi.info, Node: Top, Next: Introduction, Up: (dir) |
| |
| libffi |
| ****** |
| |
| This manual is for Libffi, a portable foreign-function interface |
| library. |
| |
| 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". |
| |
| * Menu: |
| |
| * Introduction:: What is libffi? |
| * Using libffi:: How to use libffi. |
| * Missing Features:: Things libffi can't do. |
| * Index:: Index. |
| |
| |
| File: libffi.info, Node: Introduction, Next: Using libffi, Prev: Top, Up: Top |
| |
| 1 What is libffi? |
| ***************** |
| |
| Compilers for high level languages generate code that follow certain |
| conventions. These conventions are necessary, in part, for separate |
| compilation to work. One such convention is the "calling convention". |
| 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". |
| |
| 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 |
| bridge from the interpreter program to compiled code. |
| |
| 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. |
| |
| |
| File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top |
| |
| 2 Using libffi |
| ************** |
| |
| * Menu: |
| |
| * The Basics:: The basic libffi API. |
| * Simple Example:: A simple example. |
| * Types:: libffi type descriptions. |
| * Multiple ABIs:: Different passing styles on one platform. |
| * The Closure API:: Writing a generic function. |
| * Closure Example:: A closure example. |
| |
| |
| 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 |
| 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 |
| 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'. |
| |
| -- 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. |
| |
| NARGS is the number of arguments that this function accepts. |
| |
| 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 |
| 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. |
| |
| 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. |
| |
| 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'. |
| |
| 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, 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. |
| |
| 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 |
| the callee (for instance, structs passed by value); the burden of |
| copying pass-by-value arguments is placed on the caller. |
| |
| |
| File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: Using libffi |
| |
| 2.2 Simple Example |
| ================== |
| |
| Here is a trivial example that calls 'puts' a few times. |
| |
| #include <stdio.h> |
| #include <ffi.h> |
| |
| int main() |
| { |
| ffi_cif cif; |
| ffi_type *args[1]; |
| void *values[1]; |
| char *s; |
| ffi_arg rc; |
| |
| /* Initialize the argument info vectors */ |
| args[0] = &ffi_type_pointer; |
| values[0] = &s; |
| |
| /* Initialize the cif */ |
| if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, |
| &ffi_type_sint, args) == FFI_OK) |
| { |
| s = "Hello World!"; |
| ffi_call(&cif, puts, &rc, values); |
| /* rc now holds the result of the call to puts */ |
| |
| /* values holds a pointer to the function's arg, so to |
| call puts() again all we need to do is change the |
| value of s */ |
| s = "This is cool!"; |
| ffi_call(&cif, puts, &rc, values); |
| } |
| |
| return 0; |
| } |
| |
| |
| File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, Up: Using libffi |
| |
| 2.3 Types |
| ========= |
| |
| * Menu: |
| |
| * Primitive Types:: Built-in types. |
| * Structures:: Structure types. |
| * Type Example:: Structure type example. |
| |
| |
| 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: |
| |
| 'ffi_type_void' |
| The type 'void'. This cannot be used for argument types, only for |
| return values. |
| |
| 'ffi_type_uint8' |
| An unsigned, 8-bit integer type. |
| |
| 'ffi_type_sint8' |
| A signed, 8-bit integer type. |
| |
| 'ffi_type_uint16' |
| An unsigned, 16-bit integer type. |
| |
| 'ffi_type_sint16' |
| A signed, 16-bit integer type. |
| |
| 'ffi_type_uint32' |
| An unsigned, 32-bit integer type. |
| |
| 'ffi_type_sint32' |
| A signed, 32-bit integer type. |
| |
| 'ffi_type_uint64' |
| An unsigned, 64-bit integer type. |
| |
| 'ffi_type_sint64' |
| A signed, 64-bit integer type. |
| |
| 'ffi_type_float' |
| The C 'float' type. |
| |
| 'ffi_type_double' |
| The C 'double' 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_ushort' |
| The C 'unsigned short' type. |
| |
| 'ffi_type_sshort' |
| The C 'short' type. |
| |
| 'ffi_type_uint' |
| The C 'unsigned int' type. |
| |
| 'ffi_type_sint' |
| The C 'int' type. |
| |
| 'ffi_type_ulong' |
| The C 'unsigned 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_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'. |
| |
| |
| File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types |
| |
| 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 |
| for it. |
| |
| -- 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 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' |
| objects. There is one element per field of the struct. |
| |
| |
| File: libffi.info, Node: Type Example, 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'. |
| |
| Here is how the struct is defined: |
| |
| struct tm { |
| int tm_sec; |
| int tm_min; |
| int tm_hour; |
| int tm_mday; |
| int tm_mon; |
| int tm_year; |
| int tm_wday; |
| int tm_yday; |
| int tm_isdst; |
| /* Those are for future use. */ |
| long int __tm_gmtoff__; |
| __const char *__tm_zone__; |
| }; |
| |
| Here is the corresponding code to describe this struct to 'libffi': |
| |
| { |
| ffi_type tm_type; |
| ffi_type *tm_type_elements[12]; |
| 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++) |
| tm_type_elements[i] = &ffi_type_sint; |
| |
| tm_type_elements[9] = &ffi_type_slong; |
| tm_type_elements[10] = &ffi_type_pointer; |
| tm_type_elements[11] = NULL; |
| |
| /* tm_type can now be used to represent tm argument types and |
| return types for ffi_prep_cif() */ |
| } |
| |
| |
| 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. |
| |
| 'libffi' provides some support for this. However, this is |
| necessarily platform-specific. |
| |
| |
| File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi |
| |
| 2.5 The Closure API |
| =================== |
| |
| '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. |
| |
| 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: |
| |
| -- 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. |
| |
| -- Function: void ffi_closure_free (void *WRITABLE) |
| 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 |
| closure function: |
| |
| -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE, |
| ffi_cif *CIF, void (*FUN) (ffi_cif *CIF, void *RET, void |
| **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'. |
| |
| 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'. |
| |
| 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'. |
| |
| 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'. |
| |
| 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'. |
| |
| '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 |
| appropriate pointer-to-function type. |
| |
| 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. |
| |
| |
| File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using libffi |
| |
| 2.6 Closure Example |
| =================== |
| |
| 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, void *ret, void* args[], |
| void *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; |
| |
| void *bound_puts; |
| int rc; |
| |
| /* Allocate closure and bound_puts */ |
| closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); |
| |
| if (closure) |
| { |
| /* Initialize the argument info vectors */ |
| args[0] = &ffi_type_pointer; |
| |
| /* Initialize the cif */ |
| if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, |
| &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 = ((puts_t)bound_puts)("Hello World!"); |
| /* rc now holds the result of the call to fputs */ |
| } |
| } |
| } |
| |
| /* Deallocate both closure, and bound_puts */ |
| ffi_closure_free(closure); |
| |
| return 0; |
| } |
| |
| |
| File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top |
| |
| 3 Missing Features |
| ****************** |
| |
| 'libffi' is missing a few features. We welcome patches to add support |
| for these. |
| |
| * Variadic closures. |
| |
| * There is no support for bit fields in structures. |
| |
| * The closure API is |
| |
| * 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 |
| |
| Index |
| ***** |
| |
| [index] |
| * Menu: |
| |
| * ABI: Introduction. (line 13) |
| * Application Binary Interface: Introduction. (line 13) |
| * calling convention: Introduction. (line 13) |
| * cif: The Basics. (line 14) |
| * closure API: The Closure API. (line 13) |
| * closures: The Closure API. (line 13) |
| * FFI: Introduction. (line 31) |
| * 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_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: 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_double: Primitive Types. (line 41) |
| * ffi_type_float: Primitive Types. (line 38) |
| * ffi_type_longdouble: Primitive Types. (line 71) |
| * ffi_type_pointer: Primitive Types. (line 75) |
| * ffi_type_schar: Primitive Types. (line 47) |
| * ffi_type_sint: Primitive Types. (line 62) |
| * ffi_type_sint16: Primitive Types. (line 23) |
| * ffi_type_sint32: Primitive Types. (line 29) |
| * ffi_type_sint64: Primitive Types. (line 35) |
| * ffi_type_sint8: Primitive Types. (line 17) |
| * ffi_type_slong: Primitive Types. (line 68) |
| * ffi_type_sshort: Primitive Types. (line 56) |
| * ffi_type_uchar: Primitive Types. (line 44) |
| * ffi_type_uint: Primitive Types. (line 59) |
| * ffi_type_uint16: Primitive Types. (line 20) |
| * ffi_type_uint32: Primitive Types. (line 26) |
| * ffi_type_uint64: Primitive Types. (line 32) |
| * ffi_type_uint8: Primitive Types. (line 14) |
| * ffi_type_ulong: Primitive Types. (line 65) |
| * ffi_type_ushort: Primitive Types. (line 53) |
| * ffi_type_void: Primitive Types. (line 10) |
| * Foreign Function Interface: Introduction. (line 31) |
| * void: The Basics. (line 62) |
| * void <1>: The Closure API. (line 19) |
| * void <2>: The Closure API. (line 26) |
| |
| |
| |
| Tag Table: |
| Node: Top682 |
| Node: Introduction1429 |
| Node: Using libffi3061 |
| Node: The Basics3547 |
| Node: Simple Example7198 |
| Node: Types8229 |
| Node: Primitive Types8512 |
| Node: Structures10333 |
| Node: Type Example11207 |
| Node: Multiple ABIs12473 |
| Node: The Closure API12844 |
| Node: Closure Example15788 |
| Node: Missing Features17397 |
| Node: Index17850 |
| |
| End Tag Table |