Add closure example doc

This commit is contained in:
Anthony Green
2010-01-13 02:56:19 -05:00
parent 7b7a42f221
commit edfdfd2e85
10 changed files with 2042 additions and 19 deletions

View File

@@ -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

View File

@@ -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?