xref: /aosp_15_r20/external/libffi/man/ffi_call.3 (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
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