mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-30 19:53:46 +00:00
104 lines
2.3 KiB
Groff
104 lines
2.3 KiB
Groff
|
.Dd February 15, 2008
|
||
|
.Dt ffi_call 3
|
||
|
.Sh NAME
|
||
|
.Nm ffi_call
|
||
|
.Nd Invoke a foreign function.
|
||
|
.Sh SYNOPSIS
|
||
|
.In ffi.h
|
||
|
.Ft void
|
||
|
.Fo ffi_call
|
||
|
.Fa "ffi_cif *cif"
|
||
|
.Fa "void (*fn)(void)"
|
||
|
.Fa "void *rvalue"
|
||
|
.Fa "void **avalue"
|
||
|
.Fc
|
||
|
.Sh DESCRIPTION
|
||
|
The
|
||
|
.Nm ffi_call
|
||
|
function provides a simple mechanism for invoking a function without
|
||
|
requiring knowledge of the function's interface at compile time.
|
||
|
.Fa fn
|
||
|
is called with the values retrieved from the pointers in the
|
||
|
.Fa avalue
|
||
|
array. The return value from
|
||
|
.Fa fn
|
||
|
is placed in storage pointed to by
|
||
|
.Fa rvalue .
|
||
|
.Fa cif
|
||
|
contains information describing the data types, sizes and alignments of the
|
||
|
arguments to and return value from
|
||
|
.Fa fn ,
|
||
|
and must be initialized with
|
||
|
.Nm ffi_prep_cif
|
||
|
before it is used with
|
||
|
.Nm ffi_call .
|
||
|
.Pp
|
||
|
.Fa rvalue
|
||
|
must point to storage that is sizeof(ffi_arg) or larger for non-floating point
|
||
|
types. For smaller-sized return value types, the
|
||
|
.Nm ffi_arg
|
||
|
or
|
||
|
.Nm ffi_sarg
|
||
|
integral type must be used to hold
|
||
|
the return value.
|
||
|
.Sh EXAMPLES
|
||
|
.Bd -literal
|
||
|
#include <ffi.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
unsigned char
|
||
|
foo(unsigned int, float);
|
||
|
|
||
|
int
|
||
|
main(int argc, const char **argv)
|
||
|
{
|
||
|
ffi_cif cif;
|
||
|
ffi_type *arg_types[2];
|
||
|
void *arg_values[2];
|
||
|
ffi_status status;
|
||
|
|
||
|
// Because the return value from foo() is smaller than sizeof(long), it
|
||
|
// must be passed as ffi_arg or ffi_sarg.
|
||
|
ffi_arg result;
|
||
|
|
||
|
// Specify the data type of each argument. Available types are defined
|
||
|
// in <ffi/ffi.h>.
|
||
|
arg_types[0] = &ffi_type_uint;
|
||
|
arg_types[1] = &ffi_type_float;
|
||
|
|
||
|
// Prepare the ffi_cif structure.
|
||
|
if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
|
||
|
2, &ffi_type_uint8, arg_types)) != FFI_OK)
|
||
|
{
|
||
|
// Handle the ffi_status error.
|
||
|
}
|
||
|
|
||
|
// Specify the values of each argument.
|
||
|
unsigned int arg1 = 42;
|
||
|
float arg2 = 5.1;
|
||
|
|
||
|
arg_values[0] = &arg1;
|
||
|
arg_values[1] = &arg2;
|
||
|
|
||
|
// Invoke the function.
|
||
|
ffi_call(&cif, FFI_FN(foo), &result, arg_values);
|
||
|
|
||
|
// The ffi_arg 'result' now contains the unsigned char returned from foo(),
|
||
|
// which can be accessed by a typecast.
|
||
|
printf("result is %hhu", (unsigned char)result);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// The target function.
|
||
|
unsigned char
|
||
|
foo(unsigned int x, float y)
|
||
|
{
|
||
|
unsigned char result = x - y;
|
||
|
return result;
|
||
|
}
|
||
|
.Ed
|
||
|
.Sh SEE ALSO
|
||
|
.Xr ffi 3 ,
|
||
|
.Xr ffi_prep_cif 3
|