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