Add closure example doc
This commit is contained in:
@@ -4,7 +4,7 @@ from ../libffi/doc/libffi.texi.
|
||||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
Copyright (C) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
@@ -27,7 +27,7 @@ libffi
|
||||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
Copyright (C) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
@@ -89,6 +89,7 @@ File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduc
|
||||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
* Closure Example:: A closure example.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi
|
||||
@@ -368,7 +369,7 @@ instance, the x86 platform has both `stdcall' and `fastcall' functions.
|
||||
necessarily platform-specific.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Closure API, Prev: Multiple ABIs, Up: Using libffi
|
||||
File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi
|
||||
|
||||
2.5 The Closure API
|
||||
===================
|
||||
@@ -443,6 +444,62 @@ closure function:
|
||||
is deprecated, as it cannot handle the need for separate writable and
|
||||
executable addresses.
|
||||
|
||||
|
||||
File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using libffi
|
||||
|
||||
2.6 Closure Example
|
||||
===================
|
||||
|
||||
A trivial example that creates a new `puts' by binding `fputs' with
|
||||
`stdin'.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
/* Acts like puts with the file given at time of enclosure. */
|
||||
void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
|
||||
FILE *stream)
|
||||
{
|
||||
*ret = fputs(*(char **)args[0], stream);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
ffi_closure *closure;
|
||||
|
||||
int (*bound_puts)(char *);
|
||||
int rc;
|
||||
|
||||
/* Allocate closure and bound_puts */
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
||||
|
||||
if (closure)
|
||||
{
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
{
|
||||
/* Initialize the closure, setting stream to stdout */
|
||||
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
||||
stdout, bound_puts) == FFI_OK)
|
||||
{
|
||||
rc = bound_puts("Hello World!");
|
||||
/* rc now holds the result of the call to fputs */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate both closure, and bound_puts */
|
||||
ffi_closure_free(closure);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top
|
||||
|
||||
@@ -516,18 +573,19 @@ Index
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top700
|
||||
Node: Introduction1436
|
||||
Node: Using libffi3072
|
||||
Node: The Basics3507
|
||||
Node: Simple Example6114
|
||||
Node: Types7141
|
||||
Node: Primitive Types7424
|
||||
Node: Structures9244
|
||||
Node: Type Example10104
|
||||
Node: Multiple ABIs11327
|
||||
Node: The Closure API11698
|
||||
Node: Missing Features14618
|
||||
Node: Index15111
|
||||
Node: Top706
|
||||
Node: Introduction1448
|
||||
Node: Using libffi3084
|
||||
Node: The Basics3570
|
||||
Node: Simple Example6177
|
||||
Node: Types7204
|
||||
Node: Primitive Types7487
|
||||
Node: Structures9307
|
||||
Node: Type Example10167
|
||||
Node: Multiple ABIs11390
|
||||
Node: The Closure API11761
|
||||
Node: Closure Example14705
|
||||
Node: Missing Features16264
|
||||
Node: Index16757
|
||||
|
||||
End Tag Table
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright @copyright{} 2008 Red Hat, Inc.
|
||||
Copyright @copyright{} 2008, 2010 Red Hat, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@@ -106,6 +106,7 @@ values passed between the two languages.
|
||||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
* Closure Example:: A closure example.
|
||||
@end menu
|
||||
|
||||
|
||||
@@ -500,12 +501,66 @@ After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
|
||||
to the appropriate pointer-to-function type.
|
||||
@end defun
|
||||
|
||||
@c FIXME: example
|
||||
|
||||
You may see old code referring to @code{ffi_prep_closure}. This
|
||||
function is deprecated, as it cannot handle the need for separate
|
||||
writable and executable addresses.
|
||||
|
||||
@node Closure Example
|
||||
@section Closure Example
|
||||
|
||||
A trivial example that creates a new @code{puts} by binding
|
||||
@code{fputs} with @code{stdin}.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
/* Acts like puts with the file given at time of enclosure. */
|
||||
void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
|
||||
FILE *stream)
|
||||
@{
|
||||
*ret = fputs(*(char **)args[0], stream);
|
||||
@}
|
||||
|
||||
int main()
|
||||
@{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
ffi_closure *closure;
|
||||
|
||||
int (*bound_puts)(char *);
|
||||
int rc;
|
||||
|
||||
/* Allocate closure and bound_puts */
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
||||
|
||||
if (closure)
|
||||
@{
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
@{
|
||||
/* Initialize the closure, setting stream to stdout */
|
||||
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
||||
stdout, bound_puts) == FFI_OK)
|
||||
@{
|
||||
rc = bound_puts("Hello World!");
|
||||
/* rc now holds the result of the call to fputs */
|
||||
@}
|
||||
@}
|
||||
@}
|
||||
|
||||
/* Deallocate both closure, and bound_puts */
|
||||
ffi_closure_free(closure);
|
||||
|
||||
return 0;
|
||||
@}
|
||||
|
||||
@end example
|
||||
|
||||
|
||||
@node Missing Features
|
||||
@chapter Missing Features
|
||||
@@ -525,6 +580,8 @@ There is no support for bit fields in structures.
|
||||
@item
|
||||
The closure API is
|
||||
|
||||
@c FIXME: ...
|
||||
|
||||
@item
|
||||
The ``raw'' API is undocumented.
|
||||
@c argument promotion?
|
||||
|
||||
Reference in New Issue
Block a user