Anthony Green | c6dddbd | 2009-10-04 08:11:33 -0400 | [diff] [blame] | 1 | .Dd February 15, 2008 |
| 2 | .Dt ffi_call 3 |
| 3 | .Sh NAME |
| 4 | .Nm ffi_call |
| 5 | .Nd Invoke a foreign function. |
| 6 | .Sh SYNOPSIS |
| 7 | .In ffi.h |
| 8 | .Ft void |
| 9 | .Fo ffi_call |
| 10 | .Fa "ffi_cif *cif" |
| 11 | .Fa "void (*fn)(void)" |
| 12 | .Fa "void *rvalue" |
| 13 | .Fa "void **avalue" |
| 14 | .Fc |
| 15 | .Sh DESCRIPTION |
| 16 | The |
| 17 | .Nm ffi_call |
| 18 | function provides a simple mechanism for invoking a function without |
| 19 | requiring knowledge of the function's interface at compile time. |
| 20 | .Fa fn |
| 21 | is called with the values retrieved from the pointers in the |
| 22 | .Fa avalue |
| 23 | array. The return value from |
| 24 | .Fa fn |
| 25 | is placed in storage pointed to by |
| 26 | .Fa rvalue . |
| 27 | .Fa cif |
| 28 | contains information describing the data types, sizes and alignments of the |
| 29 | arguments to and return value from |
| 30 | .Fa fn , |
| 31 | and must be initialized with |
| 32 | .Nm ffi_prep_cif |
| 33 | before it is used with |
| 34 | .Nm ffi_call . |
| 35 | .Pp |
| 36 | .Fa rvalue |
| 37 | must point to storage that is sizeof(ffi_arg) or larger for non-floating point |
| 38 | types. For smaller-sized return value types, the |
| 39 | .Nm ffi_arg |
| 40 | or |
| 41 | .Nm ffi_sarg |
| 42 | integral type must be used to hold |
| 43 | the return value. |
| 44 | .Sh EXAMPLES |
| 45 | .Bd -literal |
Anthony Green | 115ab36 | 2009-12-24 00:22:00 -0500 | [diff] [blame] | 46 | #include <ffi.h> |
Anthony Green | c6dddbd | 2009-10-04 08:11:33 -0400 | [diff] [blame] | 47 | #include <stdio.h> |
| 48 | |
| 49 | unsigned char |
| 50 | foo(unsigned int, float); |
| 51 | |
| 52 | int |
| 53 | main(int argc, const char **argv) |
| 54 | { |
| 55 | ffi_cif cif; |
| 56 | ffi_type *arg_types[2]; |
| 57 | void *arg_values[2]; |
| 58 | ffi_status status; |
| 59 | |
| 60 | // Because the return value from foo() is smaller than sizeof(long), it |
| 61 | // must be passed as ffi_arg or ffi_sarg. |
| 62 | ffi_arg result; |
| 63 | |
| 64 | // Specify the data type of each argument. Available types are defined |
| 65 | // in <ffi/ffi.h>. |
| 66 | arg_types[0] = &ffi_type_uint; |
| 67 | arg_types[1] = &ffi_type_float; |
| 68 | |
| 69 | // Prepare the ffi_cif structure. |
| 70 | if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, |
| 71 | 2, &ffi_type_uint8, arg_types)) != FFI_OK) |
| 72 | { |
| 73 | // Handle the ffi_status error. |
| 74 | } |
| 75 | |
| 76 | // Specify the values of each argument. |
| 77 | unsigned int arg1 = 42; |
| 78 | float arg2 = 5.1; |
| 79 | |
| 80 | arg_values[0] = &arg1; |
| 81 | arg_values[1] = &arg2; |
| 82 | |
| 83 | // Invoke the function. |
| 84 | ffi_call(&cif, FFI_FN(foo), &result, arg_values); |
| 85 | |
| 86 | // The ffi_arg 'result' now contains the unsigned char returned from foo(), |
| 87 | // which can be accessed by a typecast. |
| 88 | printf("result is %hhu", (unsigned char)result); |
| 89 | |
| 90 | return 0; |
| 91 | } |
| 92 | |
| 93 | // The target function. |
| 94 | unsigned char |
| 95 | foo(unsigned int x, float y) |
| 96 | { |
| 97 | unsigned char result = x - y; |
| 98 | return result; |
| 99 | } |
| 100 | .Ed |
| 101 | .Sh SEE ALSO |
| 102 | .Xr ffi 3 , |
| 103 | .Xr ffi_prep_cif 3 |