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