### 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. 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 `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 abi, unsigned int nfixedargs, unsigned int ntotalargs, 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 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. 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.