annotate libffi/doc/libffi.texi @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 \input texinfo @c -*-texinfo-*-
kono
parents:
diff changeset
2 @c %**start of header
kono
parents:
diff changeset
3 @setfilename libffi.info
kono
parents:
diff changeset
4 @settitle libffi
kono
parents:
diff changeset
5 @setchapternewpage off
kono
parents:
diff changeset
6 @c %**end of header
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 @c Merge the standard indexes into a single one.
kono
parents:
diff changeset
9 @syncodeindex fn cp
kono
parents:
diff changeset
10 @syncodeindex vr cp
kono
parents:
diff changeset
11 @syncodeindex ky cp
kono
parents:
diff changeset
12 @syncodeindex pg cp
kono
parents:
diff changeset
13 @syncodeindex tp cp
kono
parents:
diff changeset
14
kono
parents:
diff changeset
15 @include version.texi
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 @copying
kono
parents:
diff changeset
18
kono
parents:
diff changeset
19 This manual is for Libffi, a portable foreign-function interface
kono
parents:
diff changeset
20 library.
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc.
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 @quotation
kono
parents:
diff changeset
25 Permission is granted to copy, distribute and/or modify this document
kono
parents:
diff changeset
26 under the terms of the GNU General Public License as published by the
kono
parents:
diff changeset
27 Free Software Foundation; either version 2, or (at your option) any
kono
parents:
diff changeset
28 later version. A copy of the license is included in the
kono
parents:
diff changeset
29 section entitled ``GNU General Public License''.
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 @end quotation
kono
parents:
diff changeset
32 @end copying
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 @dircategory Development
kono
parents:
diff changeset
35 @direntry
kono
parents:
diff changeset
36 * libffi: (libffi). Portable foreign-function interface library.
kono
parents:
diff changeset
37 @end direntry
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 @titlepage
kono
parents:
diff changeset
40 @title Libffi
kono
parents:
diff changeset
41 @page
kono
parents:
diff changeset
42 @vskip 0pt plus 1filll
kono
parents:
diff changeset
43 @insertcopying
kono
parents:
diff changeset
44 @end titlepage
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 @ifnottex
kono
parents:
diff changeset
48 @node Top
kono
parents:
diff changeset
49 @top libffi
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 @insertcopying
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 @menu
kono
parents:
diff changeset
54 * Introduction:: What is libffi?
kono
parents:
diff changeset
55 * Using libffi:: How to use libffi.
kono
parents:
diff changeset
56 * Missing Features:: Things libffi can't do.
kono
parents:
diff changeset
57 * Index:: Index.
kono
parents:
diff changeset
58 @end menu
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 @end ifnottex
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 @node Introduction
kono
parents:
diff changeset
64 @chapter What is libffi?
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 Compilers for high level languages generate code that follow certain
kono
parents:
diff changeset
67 conventions. These conventions are necessary, in part, for separate
kono
parents:
diff changeset
68 compilation to work. One such convention is the @dfn{calling
kono
parents:
diff changeset
69 convention}. The calling convention is a set of assumptions made by
kono
parents:
diff changeset
70 the compiler about where function arguments will be found on entry to
kono
parents:
diff changeset
71 a function. A calling convention also specifies where the return
kono
parents:
diff changeset
72 value for a function is found. The calling convention is also
kono
parents:
diff changeset
73 sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}.
kono
parents:
diff changeset
74 @cindex calling convention
kono
parents:
diff changeset
75 @cindex ABI
kono
parents:
diff changeset
76 @cindex Application Binary Interface
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 Some programs may not know at the time of compilation what arguments
kono
parents:
diff changeset
79 are to be passed to a function. For instance, an interpreter may be
kono
parents:
diff changeset
80 told at run-time about the number and types of arguments used to call
kono
parents:
diff changeset
81 a given function. @samp{Libffi} can be used in such programs to
kono
parents:
diff changeset
82 provide a bridge from the interpreter program to compiled code.
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 The @samp{libffi} library provides a portable, high level programming
kono
parents:
diff changeset
85 interface to various calling conventions. This allows a programmer to
kono
parents:
diff changeset
86 call any function specified by a call interface description at run
kono
parents:
diff changeset
87 time.
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 @acronym{FFI} stands for Foreign Function Interface. A foreign
kono
parents:
diff changeset
90 function interface is the popular name for the interface that allows
kono
parents:
diff changeset
91 code written in one language to call code written in another language.
kono
parents:
diff changeset
92 The @samp{libffi} library really only provides the lowest, machine
kono
parents:
diff changeset
93 dependent layer of a fully featured foreign function interface. A
kono
parents:
diff changeset
94 layer must exist above @samp{libffi} that handles type conversions for
kono
parents:
diff changeset
95 values passed between the two languages.
kono
parents:
diff changeset
96 @cindex FFI
kono
parents:
diff changeset
97 @cindex Foreign Function Interface
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 @node Using libffi
kono
parents:
diff changeset
101 @chapter Using libffi
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 @menu
kono
parents:
diff changeset
104 * The Basics:: The basic libffi API.
kono
parents:
diff changeset
105 * Simple Example:: A simple example.
kono
parents:
diff changeset
106 * Types:: libffi type descriptions.
kono
parents:
diff changeset
107 * Multiple ABIs:: Different passing styles on one platform.
kono
parents:
diff changeset
108 * The Closure API:: Writing a generic function.
kono
parents:
diff changeset
109 * Closure Example:: A closure example.
kono
parents:
diff changeset
110 @end menu
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 @node The Basics
kono
parents:
diff changeset
114 @section The Basics
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 @samp{Libffi} assumes that you have a pointer to the function you wish
kono
parents:
diff changeset
117 to call and that you know the number and types of arguments to pass
kono
parents:
diff changeset
118 it, as well as the return type of the function.
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 The first thing you must do is create an @code{ffi_cif} object that
kono
parents:
diff changeset
121 matches the signature of the function you wish to call. This is a
kono
parents:
diff changeset
122 separate step because it is common to make multiple calls using a
kono
parents:
diff changeset
123 single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for
kono
parents:
diff changeset
124 Call InterFace. To prepare a call interface object, use the function
kono
parents:
diff changeset
125 @code{ffi_prep_cif}.
kono
parents:
diff changeset
126 @cindex cif
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 @findex ffi_prep_cif
kono
parents:
diff changeset
129 @defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
kono
parents:
diff changeset
130 This initializes @var{cif} according to the given parameters.
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 @var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what
kono
parents:
diff changeset
133 you want. @ref{Multiple ABIs} for more information.
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 @var{nargs} is the number of arguments that this function accepts.
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 @var{rtype} is a pointer to an @code{ffi_type} structure that
kono
parents:
diff changeset
138 describes the return type of the function. @xref{Types}.
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 @var{argtypes} is a vector of @code{ffi_type} pointers.
kono
parents:
diff changeset
141 @var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0,
kono
parents:
diff changeset
142 this argument is ignored.
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 @code{ffi_prep_cif} returns a @code{libffi} status code, of type
kono
parents:
diff changeset
145 @code{ffi_status}. This will be either @code{FFI_OK} if everything
kono
parents:
diff changeset
146 worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type}
kono
parents:
diff changeset
147 objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
kono
parents:
diff changeset
148 is invalid.
kono
parents:
diff changeset
149 @end defun
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 If the function being called is variadic (varargs) then
kono
parents:
diff changeset
152 @code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 @findex ffi_prep_cif_var
kono
parents:
diff changeset
155 @defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi var{abi}, unsigned int @var{nfixedargs}, unsigned int var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
kono
parents:
diff changeset
156 This initializes @var{cif} according to the given parameters for
kono
parents:
diff changeset
157 a call to a variadic function. In general it's operation is the
kono
parents:
diff changeset
158 same as for @code{ffi_prep_cif} except that:
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 @var{nfixedargs} is the number of fixed arguments, prior to any
kono
parents:
diff changeset
161 variadic arguments. It must be greater than zero.
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 @var{ntotalargs} the total number of arguments, including variadic
kono
parents:
diff changeset
164 and fixed arguments.
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 Note that, different cif's must be prepped for calls to the same
kono
parents:
diff changeset
167 function when different numbers of arguments are passed.
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 Also note that a call to @code{ffi_prep_cif_var} with
kono
parents:
diff changeset
170 @var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to
kono
parents:
diff changeset
171 @code{ffi_prep_cif}.
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 @end defun
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 To call a function using an initialized @code{ffi_cif}, use the
kono
parents:
diff changeset
177 @code{ffi_call} function:
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 @findex ffi_call
kono
parents:
diff changeset
180 @defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues})
kono
parents:
diff changeset
181 This calls the function @var{fn} according to the description given in
kono
parents:
diff changeset
182 @var{cif}. @var{cif} must have already been prepared using
kono
parents:
diff changeset
183 @code{ffi_prep_cif}.
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 @var{rvalue} is a pointer to a chunk of memory that will hold the
kono
parents:
diff changeset
186 result of the function call. This must be large enough to hold the
kono
parents:
diff changeset
187 result, no smaller than the system register size (generally 32 or 64
kono
parents:
diff changeset
188 bits), and must be suitably aligned; it is the caller's responsibility
kono
parents:
diff changeset
189 to ensure this. If @var{cif} declares that the function returns
kono
parents:
diff changeset
190 @code{void} (using @code{ffi_type_void}), then @var{rvalue} is
kono
parents:
diff changeset
191 ignored.
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 @var{avalues} is a vector of @code{void *} pointers that point to the
kono
parents:
diff changeset
194 memory locations holding the argument values for a call. If @var{cif}
kono
parents:
diff changeset
195 declares that the function has no arguments (i.e., @var{nargs} was 0),
kono
parents:
diff changeset
196 then @var{avalues} is ignored. Note that argument values may be
kono
parents:
diff changeset
197 modified by the callee (for instance, structs passed by value); the
kono
parents:
diff changeset
198 burden of copying pass-by-value arguments is placed on the caller.
kono
parents:
diff changeset
199 @end defun
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 @node Simple Example
kono
parents:
diff changeset
203 @section Simple Example
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 Here is a trivial example that calls @code{puts} a few times.
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 @example
kono
parents:
diff changeset
208 #include <stdio.h>
kono
parents:
diff changeset
209 #include <ffi.h>
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 int main()
kono
parents:
diff changeset
212 @{
kono
parents:
diff changeset
213 ffi_cif cif;
kono
parents:
diff changeset
214 ffi_type *args[1];
kono
parents:
diff changeset
215 void *values[1];
kono
parents:
diff changeset
216 char *s;
kono
parents:
diff changeset
217 ffi_arg rc;
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 /* Initialize the argument info vectors */
kono
parents:
diff changeset
220 args[0] = &ffi_type_pointer;
kono
parents:
diff changeset
221 values[0] = &s;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 /* Initialize the cif */
kono
parents:
diff changeset
224 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
kono
parents:
diff changeset
225 &ffi_type_sint, args) == FFI_OK)
kono
parents:
diff changeset
226 @{
kono
parents:
diff changeset
227 s = "Hello World!";
kono
parents:
diff changeset
228 ffi_call(&cif, puts, &rc, values);
kono
parents:
diff changeset
229 /* rc now holds the result of the call to puts */
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 /* values holds a pointer to the function's arg, so to
kono
parents:
diff changeset
232 call puts() again all we need to do is change the
kono
parents:
diff changeset
233 value of s */
kono
parents:
diff changeset
234 s = "This is cool!";
kono
parents:
diff changeset
235 ffi_call(&cif, puts, &rc, values);
kono
parents:
diff changeset
236 @}
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 return 0;
kono
parents:
diff changeset
239 @}
kono
parents:
diff changeset
240 @end example
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 @node Types
kono
parents:
diff changeset
244 @section Types
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 @menu
kono
parents:
diff changeset
247 * Primitive Types:: Built-in types.
kono
parents:
diff changeset
248 * Structures:: Structure types.
kono
parents:
diff changeset
249 * Type Example:: Structure type example.
kono
parents:
diff changeset
250 * Complex:: Complex types.
kono
parents:
diff changeset
251 * Complex Type Example:: Complex type example.
kono
parents:
diff changeset
252 @end menu
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 @node Primitive Types
kono
parents:
diff changeset
255 @subsection Primitive Types
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 @code{Libffi} provides a number of built-in type descriptors that can
kono
parents:
diff changeset
258 be used to describe argument and return types:
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 @table @code
kono
parents:
diff changeset
261 @item ffi_type_void
kono
parents:
diff changeset
262 @tindex ffi_type_void
kono
parents:
diff changeset
263 The type @code{void}. This cannot be used for argument types, only
kono
parents:
diff changeset
264 for return values.
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 @item ffi_type_uint8
kono
parents:
diff changeset
267 @tindex ffi_type_uint8
kono
parents:
diff changeset
268 An unsigned, 8-bit integer type.
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 @item ffi_type_sint8
kono
parents:
diff changeset
271 @tindex ffi_type_sint8
kono
parents:
diff changeset
272 A signed, 8-bit integer type.
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 @item ffi_type_uint16
kono
parents:
diff changeset
275 @tindex ffi_type_uint16
kono
parents:
diff changeset
276 An unsigned, 16-bit integer type.
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 @item ffi_type_sint16
kono
parents:
diff changeset
279 @tindex ffi_type_sint16
kono
parents:
diff changeset
280 A signed, 16-bit integer type.
kono
parents:
diff changeset
281
kono
parents:
diff changeset
282 @item ffi_type_uint32
kono
parents:
diff changeset
283 @tindex ffi_type_uint32
kono
parents:
diff changeset
284 An unsigned, 32-bit integer type.
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 @item ffi_type_sint32
kono
parents:
diff changeset
287 @tindex ffi_type_sint32
kono
parents:
diff changeset
288 A signed, 32-bit integer type.
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 @item ffi_type_uint64
kono
parents:
diff changeset
291 @tindex ffi_type_uint64
kono
parents:
diff changeset
292 An unsigned, 64-bit integer type.
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 @item ffi_type_sint64
kono
parents:
diff changeset
295 @tindex ffi_type_sint64
kono
parents:
diff changeset
296 A signed, 64-bit integer type.
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 @item ffi_type_float
kono
parents:
diff changeset
299 @tindex ffi_type_float
kono
parents:
diff changeset
300 The C @code{float} type.
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 @item ffi_type_double
kono
parents:
diff changeset
303 @tindex ffi_type_double
kono
parents:
diff changeset
304 The C @code{double} type.
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 @item ffi_type_uchar
kono
parents:
diff changeset
307 @tindex ffi_type_uchar
kono
parents:
diff changeset
308 The C @code{unsigned char} type.
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 @item ffi_type_schar
kono
parents:
diff changeset
311 @tindex ffi_type_schar
kono
parents:
diff changeset
312 The C @code{signed char} type. (Note that there is not an exact
kono
parents:
diff changeset
313 equivalent to the C @code{char} type in @code{libffi}; ordinarily you
kono
parents:
diff changeset
314 should either use @code{ffi_type_schar} or @code{ffi_type_uchar}
kono
parents:
diff changeset
315 depending on whether @code{char} is signed.)
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 @item ffi_type_ushort
kono
parents:
diff changeset
318 @tindex ffi_type_ushort
kono
parents:
diff changeset
319 The C @code{unsigned short} type.
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 @item ffi_type_sshort
kono
parents:
diff changeset
322 @tindex ffi_type_sshort
kono
parents:
diff changeset
323 The C @code{short} type.
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 @item ffi_type_uint
kono
parents:
diff changeset
326 @tindex ffi_type_uint
kono
parents:
diff changeset
327 The C @code{unsigned int} type.
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 @item ffi_type_sint
kono
parents:
diff changeset
330 @tindex ffi_type_sint
kono
parents:
diff changeset
331 The C @code{int} type.
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 @item ffi_type_ulong
kono
parents:
diff changeset
334 @tindex ffi_type_ulong
kono
parents:
diff changeset
335 The C @code{unsigned long} type.
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 @item ffi_type_slong
kono
parents:
diff changeset
338 @tindex ffi_type_slong
kono
parents:
diff changeset
339 The C @code{long} type.
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 @item ffi_type_longdouble
kono
parents:
diff changeset
342 @tindex ffi_type_longdouble
kono
parents:
diff changeset
343 On platforms that have a C @code{long double} type, this is defined.
kono
parents:
diff changeset
344 On other platforms, it is not.
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 @item ffi_type_pointer
kono
parents:
diff changeset
347 @tindex ffi_type_pointer
kono
parents:
diff changeset
348 A generic @code{void *} pointer. You should use this for all
kono
parents:
diff changeset
349 pointers, regardless of their real type.
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 @item ffi_type_complex_float
kono
parents:
diff changeset
352 @tindex ffi_type_complex_float
kono
parents:
diff changeset
353 The C @code{_Complex float} type.
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 @item ffi_type_complex_double
kono
parents:
diff changeset
356 @tindex ffi_type_complex_double
kono
parents:
diff changeset
357 The C @code{_Complex double} type.
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 @item ffi_type_complex_longdouble
kono
parents:
diff changeset
360 @tindex ffi_type_complex_longdouble
kono
parents:
diff changeset
361 The C @code{_Complex long double} type.
kono
parents:
diff changeset
362 On platforms that have a C @code{long double} type, this is defined.
kono
parents:
diff changeset
363 On other platforms, it is not.
kono
parents:
diff changeset
364 @end table
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 Each of these is of type @code{ffi_type}, so you must take the address
kono
parents:
diff changeset
367 when passing to @code{ffi_prep_cif}.
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 @node Structures
kono
parents:
diff changeset
371 @subsection Structures
kono
parents:
diff changeset
372
kono
parents:
diff changeset
373 Although @samp{libffi} has no special support for unions or
kono
parents:
diff changeset
374 bit-fields, it is perfectly happy passing structures back and forth.
kono
parents:
diff changeset
375 You must first describe the structure to @samp{libffi} by creating a
kono
parents:
diff changeset
376 new @code{ffi_type} object for it.
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 @tindex ffi_type
kono
parents:
diff changeset
379 @deftp {Data type} ffi_type
kono
parents:
diff changeset
380 The @code{ffi_type} has the following members:
kono
parents:
diff changeset
381 @table @code
kono
parents:
diff changeset
382 @item size_t size
kono
parents:
diff changeset
383 This is set by @code{libffi}; you should initialize it to zero.
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 @item unsigned short alignment
kono
parents:
diff changeset
386 This is set by @code{libffi}; you should initialize it to zero.
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 @item unsigned short type
kono
parents:
diff changeset
389 For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 @item ffi_type **elements
kono
parents:
diff changeset
392 This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
kono
parents:
diff changeset
393 objects. There is one element per field of the struct.
kono
parents:
diff changeset
394 @end table
kono
parents:
diff changeset
395 @end deftp
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 @node Type Example
kono
parents:
diff changeset
399 @subsection Type Example
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 The following example initializes a @code{ffi_type} object
kono
parents:
diff changeset
402 representing the @code{tm} struct from Linux's @file{time.h}.
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 Here is how the struct is defined:
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 @example
kono
parents:
diff changeset
407 struct tm @{
kono
parents:
diff changeset
408 int tm_sec;
kono
parents:
diff changeset
409 int tm_min;
kono
parents:
diff changeset
410 int tm_hour;
kono
parents:
diff changeset
411 int tm_mday;
kono
parents:
diff changeset
412 int tm_mon;
kono
parents:
diff changeset
413 int tm_year;
kono
parents:
diff changeset
414 int tm_wday;
kono
parents:
diff changeset
415 int tm_yday;
kono
parents:
diff changeset
416 int tm_isdst;
kono
parents:
diff changeset
417 /* Those are for future use. */
kono
parents:
diff changeset
418 long int __tm_gmtoff__;
kono
parents:
diff changeset
419 __const char *__tm_zone__;
kono
parents:
diff changeset
420 @};
kono
parents:
diff changeset
421 @end example
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 Here is the corresponding code to describe this struct to
kono
parents:
diff changeset
424 @code{libffi}:
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 @example
kono
parents:
diff changeset
427 @{
kono
parents:
diff changeset
428 ffi_type tm_type;
kono
parents:
diff changeset
429 ffi_type *tm_type_elements[12];
kono
parents:
diff changeset
430 int i;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 tm_type.size = tm_type.alignment = 0;
kono
parents:
diff changeset
433 tm_type.type = FFI_TYPE_STRUCT;
kono
parents:
diff changeset
434 tm_type.elements = &tm_type_elements;
kono
parents:
diff changeset
435
kono
parents:
diff changeset
436 for (i = 0; i < 9; i++)
kono
parents:
diff changeset
437 tm_type_elements[i] = &ffi_type_sint;
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 tm_type_elements[9] = &ffi_type_slong;
kono
parents:
diff changeset
440 tm_type_elements[10] = &ffi_type_pointer;
kono
parents:
diff changeset
441 tm_type_elements[11] = NULL;
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 /* tm_type can now be used to represent tm argument types and
kono
parents:
diff changeset
444 return types for ffi_prep_cif() */
kono
parents:
diff changeset
445 @}
kono
parents:
diff changeset
446 @end example
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 @node Complex
kono
parents:
diff changeset
449 @subsection Complex Types
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 @samp{libffi} supports the complex types defined by the C99
kono
parents:
diff changeset
452 standard (@code{_Complex float}, @code{_Complex double} and
kono
parents:
diff changeset
453 @code{_Complex long double} with the built-in type descriptors
kono
parents:
diff changeset
454 @code{ffi_type_complex_float}, @code{ffi_type_complex_double} and
kono
parents:
diff changeset
455 @code{ffi_type_complex_longdouble}.
kono
parents:
diff changeset
456
kono
parents:
diff changeset
457 Custom complex types like @code{_Complex int} can also be used.
kono
parents:
diff changeset
458 An @code{ffi_type} object has to be defined to describe the
kono
parents:
diff changeset
459 complex type to @samp{libffi}.
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 @tindex ffi_type
kono
parents:
diff changeset
462 @deftp {Data type} ffi_type
kono
parents:
diff changeset
463 @table @code
kono
parents:
diff changeset
464 @item size_t size
kono
parents:
diff changeset
465 This must be manually set to the size of the complex type.
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 @item unsigned short alignment
kono
parents:
diff changeset
468 This must be manually set to the alignment of the complex type.
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 @item unsigned short type
kono
parents:
diff changeset
471 For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}.
kono
parents:
diff changeset
472
kono
parents:
diff changeset
473 @item ffi_type **elements
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 This is a @samp{NULL}-terminated array of pointers to
kono
parents:
diff changeset
476 @code{ffi_type} objects. The first element is set to the
kono
parents:
diff changeset
477 @code{ffi_type} of the complex's base type. The second element
kono
parents:
diff changeset
478 must be set to @code{NULL}.
kono
parents:
diff changeset
479 @end table
kono
parents:
diff changeset
480 @end deftp
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 The section @ref{Complex Type Example} shows a way to determine
kono
parents:
diff changeset
483 the @code{size} and @code{alignment} members in a platform
kono
parents:
diff changeset
484 independent way.
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 For platforms that have no complex support in @code{libffi} yet,
kono
parents:
diff changeset
487 the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort
kono
parents:
diff changeset
488 the program if they encounter a complex type.
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 @node Complex Type Example
kono
parents:
diff changeset
491 @subsection Complex Type Example
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 This example demonstrates how to use complex types:
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 @example
kono
parents:
diff changeset
496 #include <stdio.h>
kono
parents:
diff changeset
497 #include <ffi.h>
kono
parents:
diff changeset
498 #include <complex.h>
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 void complex_fn(_Complex float cf,
kono
parents:
diff changeset
501 _Complex double cd,
kono
parents:
diff changeset
502 _Complex long double cld)
kono
parents:
diff changeset
503 @{
kono
parents:
diff changeset
504 printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
kono
parents:
diff changeset
505 (float)creal (cf), (float)cimag (cf),
kono
parents:
diff changeset
506 (float)creal (cd), (float)cimag (cd),
kono
parents:
diff changeset
507 (float)creal (cld), (float)cimag (cld));
kono
parents:
diff changeset
508 @}
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 int main()
kono
parents:
diff changeset
511 @{
kono
parents:
diff changeset
512 ffi_cif cif;
kono
parents:
diff changeset
513 ffi_type *args[3];
kono
parents:
diff changeset
514 void *values[3];
kono
parents:
diff changeset
515 _Complex float cf;
kono
parents:
diff changeset
516 _Complex double cd;
kono
parents:
diff changeset
517 _Complex long double cld;
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 /* Initialize the argument info vectors */
kono
parents:
diff changeset
520 args[0] = &ffi_type_complex_float;
kono
parents:
diff changeset
521 args[1] = &ffi_type_complex_double;
kono
parents:
diff changeset
522 args[2] = &ffi_type_complex_longdouble;
kono
parents:
diff changeset
523 values[0] = &cf;
kono
parents:
diff changeset
524 values[1] = &cd;
kono
parents:
diff changeset
525 values[2] = &cld;
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 /* Initialize the cif */
kono
parents:
diff changeset
528 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
kono
parents:
diff changeset
529 &ffi_type_void, args) == FFI_OK)
kono
parents:
diff changeset
530 @{
kono
parents:
diff changeset
531 cf = 1.0 + 20.0 * I;
kono
parents:
diff changeset
532 cd = 300.0 + 4000.0 * I;
kono
parents:
diff changeset
533 cld = 50000.0 + 600000.0 * I;
kono
parents:
diff changeset
534 /* Call the function */
kono
parents:
diff changeset
535 ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
kono
parents:
diff changeset
536 @}
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 return 0;
kono
parents:
diff changeset
539 @}
kono
parents:
diff changeset
540 @end example
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 This is an example for defining a custom complex type descriptor
kono
parents:
diff changeset
543 for compilers that support them:
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 @example
kono
parents:
diff changeset
546 /*
kono
parents:
diff changeset
547 * This macro can be used to define new complex type descriptors
kono
parents:
diff changeset
548 * in a platform independent way.
kono
parents:
diff changeset
549 *
kono
parents:
diff changeset
550 * name: Name of the new descriptor is ffi_type_complex_<name>.
kono
parents:
diff changeset
551 * type: The C base type of the complex type.
kono
parents:
diff changeset
552 */
kono
parents:
diff changeset
553 #define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
kono
parents:
diff changeset
554 static ffi_type *ffi_elements_complex_##name [2] = @{ \
kono
parents:
diff changeset
555 (ffi_type *)(&ffitype), NULL \
kono
parents:
diff changeset
556 @}; \
kono
parents:
diff changeset
557 struct struct_align_complex_##name @{ \
kono
parents:
diff changeset
558 char c; \
kono
parents:
diff changeset
559 _Complex type x; \
kono
parents:
diff changeset
560 @}; \
kono
parents:
diff changeset
561 ffi_type ffi_type_complex_##name = @{ \
kono
parents:
diff changeset
562 sizeof(_Complex type), \
kono
parents:
diff changeset
563 offsetof(struct struct_align_complex_##name, x), \
kono
parents:
diff changeset
564 FFI_TYPE_COMPLEX, \
kono
parents:
diff changeset
565 (ffi_type **)ffi_elements_complex_##name \
kono
parents:
diff changeset
566 @}
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 /* Define new complex type descriptors using the macro: */
kono
parents:
diff changeset
569 /* ffi_type_complex_sint */
kono
parents:
diff changeset
570 FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
kono
parents:
diff changeset
571 /* ffi_type_complex_uchar */
kono
parents:
diff changeset
572 FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
kono
parents:
diff changeset
573 @end example
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 The new type descriptors can then be used like one of the built-in
kono
parents:
diff changeset
576 type descriptors in the previous example.
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 @node Multiple ABIs
kono
parents:
diff changeset
579 @section Multiple ABIs
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 A given platform may provide multiple different ABIs at once. For
kono
parents:
diff changeset
582 instance, the x86 platform has both @samp{stdcall} and @samp{fastcall}
kono
parents:
diff changeset
583 functions.
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 @code{libffi} provides some support for this. However, this is
kono
parents:
diff changeset
586 necessarily platform-specific.
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 @c FIXME: document the platforms
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 @node The Closure API
kono
parents:
diff changeset
591 @section The Closure API
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 @code{libffi} also provides a way to write a generic function -- a
kono
parents:
diff changeset
594 function that can accept and decode any combination of arguments.
kono
parents:
diff changeset
595 This can be useful when writing an interpreter, or to provide wrappers
kono
parents:
diff changeset
596 for arbitrary functions.
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 This facility is called the @dfn{closure API}. Closures are not
kono
parents:
diff changeset
599 supported on all platforms; you can check the @code{FFI_CLOSURES}
kono
parents:
diff changeset
600 define to determine whether they are supported on the current
kono
parents:
diff changeset
601 platform.
kono
parents:
diff changeset
602 @cindex closures
kono
parents:
diff changeset
603 @cindex closure API
kono
parents:
diff changeset
604 @findex FFI_CLOSURES
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 Because closures work by assembling a tiny function at runtime, they
kono
parents:
diff changeset
607 require special allocation on platforms that have a non-executable
kono
parents:
diff changeset
608 heap. Memory management for closures is handled by a pair of
kono
parents:
diff changeset
609 functions:
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 @findex ffi_closure_alloc
kono
parents:
diff changeset
612 @defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code})
kono
parents:
diff changeset
613 Allocate a chunk of memory holding @var{size} bytes. This returns a
kono
parents:
diff changeset
614 pointer to the writable address, and sets *@var{code} to the
kono
parents:
diff changeset
615 corresponding executable address.
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 @var{size} should be sufficient to hold a @code{ffi_closure} object.
kono
parents:
diff changeset
618 @end defun
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 @findex ffi_closure_free
kono
parents:
diff changeset
621 @defun void ffi_closure_free (void *@var{writable})
kono
parents:
diff changeset
622 Free memory allocated using @code{ffi_closure_alloc}. The argument is
kono
parents:
diff changeset
623 the writable address that was returned.
kono
parents:
diff changeset
624 @end defun
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 Once you have allocated the memory for a closure, you must construct a
kono
parents:
diff changeset
628 @code{ffi_cif} describing the function call. Finally you can prepare
kono
parents:
diff changeset
629 the closure function:
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 @findex ffi_prep_closure_loc
kono
parents:
diff changeset
632 @defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
kono
parents:
diff changeset
633 Prepare a closure function.
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 @var{closure} is the address of a @code{ffi_closure} object; this is
kono
parents:
diff changeset
636 the writable address returned by @code{ffi_closure_alloc}.
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 @var{cif} is the @code{ffi_cif} describing the function parameters.
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 @var{user_data} is an arbitrary datum that is passed, uninterpreted,
kono
parents:
diff changeset
641 to your closure function.
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 @var{codeloc} is the executable address returned by
kono
parents:
diff changeset
644 @code{ffi_closure_alloc}.
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 @var{fun} is the function which will be called when the closure is
kono
parents:
diff changeset
647 invoked. It is called with the arguments:
kono
parents:
diff changeset
648 @table @var
kono
parents:
diff changeset
649 @item cif
kono
parents:
diff changeset
650 The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 @item ret
kono
parents:
diff changeset
653 A pointer to the memory used for the function's return value.
kono
parents:
diff changeset
654 @var{fun} must fill this, unless the function is declared as returning
kono
parents:
diff changeset
655 @code{void}.
kono
parents:
diff changeset
656 @c FIXME: is this NULL for void-returning functions?
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 @item args
kono
parents:
diff changeset
659 A vector of pointers to memory holding the arguments to the function.
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 @item user_data
kono
parents:
diff changeset
662 The same @var{user_data} that was passed to
kono
parents:
diff changeset
663 @code{ffi_prep_closure_loc}.
kono
parents:
diff changeset
664 @end table
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 @code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
kono
parents:
diff changeset
667 went ok, and something else on error.
kono
parents:
diff changeset
668 @c FIXME: what?
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
kono
parents:
diff changeset
671 to the appropriate pointer-to-function type.
kono
parents:
diff changeset
672 @end defun
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 You may see old code referring to @code{ffi_prep_closure}. This
kono
parents:
diff changeset
675 function is deprecated, as it cannot handle the need for separate
kono
parents:
diff changeset
676 writable and executable addresses.
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 @node Closure Example
kono
parents:
diff changeset
679 @section Closure Example
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 A trivial example that creates a new @code{puts} by binding
kono
parents:
diff changeset
682 @code{fputs} with @code{stdout}.
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 @example
kono
parents:
diff changeset
685 #include <stdio.h>
kono
parents:
diff changeset
686 #include <ffi.h>
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 /* Acts like puts with the file given at time of enclosure. */
kono
parents:
diff changeset
689 void puts_binding(ffi_cif *cif, void *ret, void* args[],
kono
parents:
diff changeset
690 void *stream)
kono
parents:
diff changeset
691 @{
kono
parents:
diff changeset
692 *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
kono
parents:
diff changeset
693 @}
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 typedef int (*puts_t)(char *);
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 int main()
kono
parents:
diff changeset
698 @{
kono
parents:
diff changeset
699 ffi_cif cif;
kono
parents:
diff changeset
700 ffi_type *args[1];
kono
parents:
diff changeset
701 ffi_closure *closure;
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 void *bound_puts;
kono
parents:
diff changeset
704 int rc;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 /* Allocate closure and bound_puts */
kono
parents:
diff changeset
707 closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 if (closure)
kono
parents:
diff changeset
710 @{
kono
parents:
diff changeset
711 /* Initialize the argument info vectors */
kono
parents:
diff changeset
712 args[0] = &ffi_type_pointer;
kono
parents:
diff changeset
713
kono
parents:
diff changeset
714 /* Initialize the cif */
kono
parents:
diff changeset
715 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
kono
parents:
diff changeset
716 &ffi_type_sint, args) == FFI_OK)
kono
parents:
diff changeset
717 @{
kono
parents:
diff changeset
718 /* Initialize the closure, setting stream to stdout */
kono
parents:
diff changeset
719 if (ffi_prep_closure_loc(closure, &cif, puts_binding,
kono
parents:
diff changeset
720 stdout, bound_puts) == FFI_OK)
kono
parents:
diff changeset
721 @{
kono
parents:
diff changeset
722 rc = ((puts_t)bound_puts)("Hello World!");
kono
parents:
diff changeset
723 /* rc now holds the result of the call to fputs */
kono
parents:
diff changeset
724 @}
kono
parents:
diff changeset
725 @}
kono
parents:
diff changeset
726 @}
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 /* Deallocate both closure, and bound_puts */
kono
parents:
diff changeset
729 ffi_closure_free(closure);
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 return 0;
kono
parents:
diff changeset
732 @}
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 @end example
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 @node Missing Features
kono
parents:
diff changeset
738 @chapter Missing Features
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 @code{libffi} is missing a few features. We welcome patches to add
kono
parents:
diff changeset
741 support for these.
kono
parents:
diff changeset
742
kono
parents:
diff changeset
743 @itemize @bullet
kono
parents:
diff changeset
744 @item
kono
parents:
diff changeset
745 Variadic closures.
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 @item
kono
parents:
diff changeset
748 There is no support for bit fields in structures.
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 @item
kono
parents:
diff changeset
751 The ``raw'' API is undocumented.
kono
parents:
diff changeset
752 @c argument promotion?
kono
parents:
diff changeset
753 @c unions?
kono
parents:
diff changeset
754 @c anything else?
kono
parents:
diff changeset
755 @end itemize
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 Note that variadic support is very new and tested on a relatively
kono
parents:
diff changeset
758 small number of platforms.
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 @node Index
kono
parents:
diff changeset
761 @unnumbered Index
kono
parents:
diff changeset
762
kono
parents:
diff changeset
763 @printindex cp
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 @bye