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