-Using libffi
-============
-
- 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. The cif in ffi_cif
-stands for Call InterFace. To prepare a call interface object, use the
-following function:
-
-ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
- unsigned int nargs,
- ffi_type *rtype, ffi_type **atypes);
-
- CIF is a pointer to the call interface object you wish
- to initialize.
-
- ABI is an enum that specifies the calling convention
- to use for the call. FFI_DEFAULT_ABI defaults
- to the system's native calling convention. Other
- ABI's may be used with care. They are system
- specific.
-
- NARGS is the number of arguments this function accepts.
- libffi does not yet support vararg functions.
-
- RTYPE is a pointer to an ffi_type structure that represents
- the return type of the function. Ffi_type objects
- describe the types of values. libffi provides
- ffi_type objects for many of the native C types:
- signed int, unsigned int, signed char, unsigned char,
- etc. There is also a pointer ffi_type object and
- a void ffi_type. Use &ffi_type_void for functions that
- don't return values.
-
- ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
- If NARGS is 0, this is ignored.
-
-
-ffi_prep_cif will return a status code that you are responsible
-for checking. It will be one of the following:
-
- FFI_OK - All is good.
-
- FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
- came across is bad.
-
-
-Before making the call, the VALUES vector should be initialized
-with pointers to the appropriate argument values.
-
-To call the the function using the initialized ffi_cif, use the
-ffi_call function:
-
-void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
-
- CIF is a pointer to the ffi_cif initialized specifically
- for this function.
-
- FN is a pointer to the function you want to call.
-
- RVALUE is a pointer to a chunk of memory that is to hold the
- result of the function call. Currently, it must be
- at least one word in size (except for the n32 version
- under Irix 6.x, which must be a pointer to an 8 byte
- aligned value (a long long). It must also be at least
- word aligned (depending on the return type, and the
- system's alignment requirements). If RTYPE is
- &ffi_type_void, this is ignored. If RVALUE is NULL,
- the return value is discarded.
-
- AVALUES is a vector of void* that point to the memory locations
- holding the argument values for a call.
- If NARGS is 0, this is ignored.
-
-
-If you are expecting a return value from FN it will have been stored
-at RVALUE.
-
-
-
- An 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;
- }
-
-
-
- Aggregate Types
- ---------------
-
-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. Here is the definition of ffi_type:
-
- typedef struct _ffi_type
- {
- unsigned size;
- short alignment;
- short type;
- struct _ffi_type **elements;
- } ffi_type;
-
-All structures must have type set to FFI_TYPE_STRUCT. You may set
-size and alignment to 0. These will be calculated and reset to the
-appropriate values by ffi_prep_cif().
-
-elements is a NULL terminated array of pointers to ffi_type objects
-that describe the type of the structure elements. These may, in turn,
-be structure elements.
-
-The following example initializes a ffi_type object representing the
-tm struct from Linux's time.h:
-
- 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__;
- };
-
- {
- 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() */
- }
-
-
-
-Platform Specific Notes
-=======================
-
- Intel x86
- ---------
-
-There are no known problems with the x86 port.
-
- Sun SPARC - SunOS 4.1.3 & Solaris 2.x
- -------------------------------------
-
-You must use GNU Make to build libffi on Sun platforms.
-
- MIPS - Irix 5.3 & 6.x
- ---------------------
-
-Irix 6.2 and better supports three different calling conventions: o32,
-n32 and n64. Currently, libffi only supports both o32 and n32 under
-Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
-configured for whichever calling convention it was built for.
-
-By default, the configure script will try to build libffi with the GNU
-development tools. To build libffi with the SGI development tools, set
-the environment variable CC to either "cc -32" or "cc -n32" before
-running configure under Irix 6.x (depending on whether you want an o32
-or n32 library), or just "cc" for Irix 5.3.
-
-With the n32 calling convention, when returning structures smaller
-than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
-Here's one way of forcing this:
-
- double struct_storage[2];
- my_small_struct *s = (my_small_struct *) struct_storage;
- /* Use s for RVALUE */