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.
In most situations, ‘libffi’ will handle promotion according to
the ABI. However, for historical reasons, there is a special case
with return values that must be handled by your code. In particular,
for integral (not struct) types that are narrower than the
system register size, the return value will be widened by
‘libffi’. ‘libffi’ provides a type, ffi_arg, that
can be used as the return type. For example, if the CIF was defined
with a return type of char, ‘libffi’ will try to store a
full ffi_arg into the return value.
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.
Note that while the return value must be register-sized, arguments
should exactly match their declared type. For example, if an argument
is a short, then the entry in avalues should point to an
object declared as short; but if the return type is
short, then rvalue should point to an object declared as
a larger type – usually ffi_arg.