‘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
ffi_cif. The cif in
ffi_cif stands for
Call InterFace. To prepare a call interface object, use the function
This initializes cif according to the given parameters.
abi is the ABI to use; normally
FFI_DEFAULT_ABI is what
you want. 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. See Types.
argtypes is a vector of
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
FFI_BAD_TYPEDEF if one of the
objects is incorrect; or
FFI_BAD_ABI if the abi parameter
If the function being called is variadic (varargs) then
ffi_prep_cif_var must be used instead of
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
nfixedargs=nototalargs is NOT equivalent to a call to
To call a function using an initialized
ffi_cif, use the
This calls the function fn according to the description given in
cif. cif must have already been prepared using
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
ffi_type_void), then rvalue is
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.