b7b857bbe2
2009-06-08 Andrew Haley <aph@redhat.com> Import from libffi 3.0.8: * doc/libffi.texi: New file. * doc/libffi.info: Likewise. * doc/stamp-vti: Likewise. * man/Makefile.am: New file. * man/ffi_call.3: New file. * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, src/dlmalloc.c. (nodist_libffi_la_SOURCES): Add X86_FREEBSD. * configure.ac: Bump version to 3.0.8. parisc*-*-linux*: Add. i386-*-freebsd* | i386-*-openbsd*: Add. powerpc-*-beos*: Add. AM_CONDITIONAL X86_FREEBSD: Add. AC_CONFIG_FILES: Add man/Makefile. * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). From-SVN: r148309
534 lines
18 KiB
Plaintext
534 lines
18 KiB
Plaintext
This is doc/libffi.info, produced by makeinfo version 4.12 from
|
||
./doc/libffi.texi.
|
||
|
||
This manual is for Libffi, a portable foreign-function interface
|
||
library.
|
||
|
||
Copyright (C) 2008 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
|
||
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 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.
|
||
|
||
|
||
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.
|
||
`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
|
||
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.
|
||
|
||
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 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.
|
||
|
||
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.
|
||
|
||
|
||
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;
|
||
int 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_uint, 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.
|
||
|
||
-- 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.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, 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: 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.
|
||
|
||
* 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.
|
||
|
||
* There is no support for bit fields in structures.
|
||
|
||
* The closure API is
|
||
|
||
* The "raw" API is undocumented.
|
||
|
||
|
||
File: libffi.info, Node: Index, Prev: Missing Features, Up: Top
|
||
|
||
Index
|
||
*****
|
||
|
||
|