This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

A closure API example


Hi,

I'm not sure if this is the best place to send patches (or indeed how
one is supposed to actually use git format-patch), but attached is a
formatted commit to provide an example for the closure API documentation.

Thank you for the phenomenally useful tool.

Conrad
>From 214aaf423778a397499d6f009e42d3e629f17182 Mon Sep 17 00:00:00 2001
From: Conrad Irwin <conrad.irwin@gmail.com>
Date: Tue, 12 Jan 2010 19:10:56 +0000
Subject: [PATCH] Add a closure example to the documentation

---
 doc/libffi.info |   94 ++++++++++++++++++++++++++++++++++++++++++++----------
 doc/libffi.texi |   60 ++++++++++++++++++++++++++++++++++-
 2 files changed, 134 insertions(+), 20 deletions(-)

diff --git a/doc/libffi.info b/doc/libffi.info
index 7a8890e..c5e2925 100644
--- a/doc/libffi.info
+++ b/doc/libffi.info
@@ -1,5 +1,5 @@
-This is ../libffi/doc/libffi.info, produced by makeinfo version 4.13
-from ../libffi/doc/libffi.texi.
+This is doc/libffi.info, produced by makeinfo version 4.13 from
+./doc/libffi.texi.
 
 This manual is for Libffi, a portable foreign-function interface
 library.
@@ -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
 ===================
@@ -386,9 +387,9 @@ determine whether they are supported on the current platform.
 require special allocation on platforms that have a non-executable
 heap.  Memory management for closures is handled by a pair of functions:
 
- -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE)
+ -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODELOC)
      Allocate a chunk of memory holding SIZE bytes.  This returns a
-     pointer to the writable address, and sets *CODE to the
+     pointer to the writable address, and sets *CODELOC to the
      corresponding executable address.
 
      SIZE should be sufficient to hold a `ffi_closure' object.
@@ -444,6 +445,62 @@ 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
 
 3 Missing Features
@@ -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: Top682
+Node: Introduction1418
+Node: Using libffi3054
+Node: The Basics3540
+Node: Simple Example6147
+Node: Types7174
+Node: Primitive Types7457
+Node: Structures9277
+Node: Type Example10137
+Node: Multiple ABIs11360
+Node: The Closure API11731
+Node: Closure Example14681
+Node: Missing Features16238
+Node: Index16731
 
 End Tag Table
diff --git a/doc/libffi.texi b/doc/libffi.texi
index 9a5060d..9e410e9 100644
--- a/doc/libffi.texi
+++ b/doc/libffi.texi
@@ -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,65 @@ 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 +579,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?
-- 
1.6.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]