guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. release_1-9-9-44-g717


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-9-44-g7172599
Date: Mon, 05 Apr 2010 22:43:41 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=71725997c756e11e434983a8a19b4b205dc4265a

The branch, master has been updated
       via  71725997c756e11e434983a8a19b4b205dc4265a (commit)
      from  dcc69bab8c410a15529f9b7bcaf05cc138b23438 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 71725997c756e11e434983a8a19b4b205dc4265a
Author: Andy Wingo <address@hidden>
Date:   Tue Apr 6 00:45:35 2010 +0200

    more ffi docs
    
    * libguile/foreign.c (scm_make_foreign_function): Doc a little.
    * doc/ref/api-foreign.texi (Foreign Function Interface): Document some
      more.

-----------------------------------------------------------------------

Summary of changes:
 doc/ref/api-foreign.texi |  299 +++++++++++++++++++++++++++++++++++++--------
 libguile/foreign.c       |    8 +-
 2 files changed, 253 insertions(+), 54 deletions(-)

diff --git a/doc/ref/api-foreign.texi b/doc/ref/api-foreign.texi
index 9e4bd79..1e735db 100644
--- a/doc/ref/api-foreign.texi
+++ b/doc/ref/api-foreign.texi
@@ -25,8 +25,8 @@ prodedures.
 * Foreign Functions::           Simple calls to C procedures.
 * C Extensions::                Extending Guile in C with loadable modules.
 * Modules and Extensions::      Loading C extensions into modules.
-* Foreign Values::              Accessing global variables.
-* Dynamic FFI::                 Fu.
+* Foreign Pointers::            Accessing global variables.
+* Dynamic FFI::                 Calling arbitrary C functions.
 @end menu
 
 
@@ -101,23 +101,19 @@ called on @var{dobj}, its content is no longer accessible.
 @end deffn
 
 @smallexample
-(define libc-obj (dynamic-link "libc.so"))
-libc-obj
address@hidden #<dynamic-object "libc.so">
-(dynamic-args-call 'rand libc-obj '())
address@hidden 269167349
-(dynamic-unlink libc-obj)
-libc-obj
address@hidden #<dynamic-object "libc.so" (unlinked)>
+(define libgl-obj (dynamic-link "libGL"))
+libgl-obj
address@hidden #<dynamic-object "libGL">
+(dynamic-unlink libGL-obj)
+libGL-obj
address@hidden #<dynamic-object "libGL" (unlinked)>
 @end smallexample
 
 As you can see, after calling @code{dynamic-unlink} on a dynamically
 linked library, it is marked as @samp{(unlinked)} and you are no longer
 able to use it with @code{dynamic-call}, etc.  Whether the library is
 really removed from you program is system-dependent and will generally
-not happen when some other parts of your program still use it.  In the
-example above, @code{libc} is almost certainly not removed from your
-program because it is badly needed by almost everything.
+not happen when some other parts of your program still use it.
 
 When dynamic linking is disabled or not supported on your system,
 the above functions throw errors, but they are still available.
@@ -166,7 +162,7 @@ then add new primitives to Guile. For example, we do not 
expect that you
 will dynamically link @file{libX11} with @code{dynamic-link} and then
 construct a beautiful graphical user interface just by using
 @code{dynamic-call}. Instead, the usual way would be to write a special
-Guile<->X11 glue library that has intimate knowledge about both Guile
+Guile-to-X11 glue library that has intimate knowledge about both Guile
 and X11 and does whatever is necessary to make them inter-operate
 smoothly. This glue library could then be dynamically linked into a
 vanilla Guile interpreter and activated by calling its initialization
@@ -342,43 +338,6 @@ guile> (apropos "j0")
 
 That's it!
 
address@hidden {Scheme Procedure} load-extension lib init
address@hidden {C Function} scm_load_extension (lib, init)
-Load and initialize the extension designated by LIB and INIT.
-When there is no pre-registered function for LIB/INIT, this is
-equivalent to
-
address@hidden
-(dynamic-call INIT (dynamic-link LIB))
address@hidden lisp
-
-When there is a pre-registered function, that function is called
-instead.
-
-Normally, there is no pre-registered function.  This option exists
-only for situations where dynamic linking is unavailable or unwanted.
-In that case, you would statically link your program with the desired
-library, and register its init function right after Guile has been
-initialized.
-
-LIB should be a string denoting a shared library without any file type
-suffix such as ".so".  The suffix is provided automatically.  It
-should also not contain any directory components.  Libraries that
-implement Guile Extensions should be put into the normal locations for
-shared libraries.  We recommend to use the naming convention
-libguile-bla-blum for a extension related to a module `(bla blum)'.
-
-The normal way for a extension to be used is to write a small Scheme
-file that defines a module, and to load the extension into this
-module.  When the module is auto-loaded, the extension is loaded as
-well.  For example,
-
address@hidden
-(define-module (bla blum))
-
-(load-extension "libguile-bla-blum" "bla_init_blum")
address@hidden lisp
address@hidden deffn
 
 @node Modules and Extensions
 @subsection Modules and Extensions
@@ -473,8 +432,75 @@ itself accordingly (allowing for features not available in 
an older
 version for instance).
 
 
address@hidden Foreign Values
address@hidden Foreign Values
address@hidden Foreign Pointers
address@hidden Foreign Pointers
+
+The previous sections have shown how Guile can be extended at runtime by
+loading compiled C extensions. This approach is all well and good, but
+wouldn't it be nice if we didn't have to write any C at all? This
+section takes up the problem of accessing C values from Scheme, and the
+next discusses C functions.
+
address@hidden
+* Foreign Types::  foo
+* Foreign Variables::  foo
+* Foreign Pointers and Values::  foo
address@hidden menu
+
address@hidden Foreign Types
address@hidden Foreign Types
+
+The first impedance mismatch that one sees between C and Scheme is that
+in C, the storage locations (variables) are typed, but in Scheme types
+are associated with values, not variables. @xref{Values and Variables}.
+
+So when accessing a C value from Scheme, we must give the type of the
+value explicitly, as a parameter to any procedure that translates
+between Scheme and C values.
+
+These ``C type values'' may be constructed using the constants and
+procedures from the @code{(system foreign)} module, which may be loaded
+like this:
+
address@hidden
+(use-modules (system foreign))
address@hidden example
+
address@hidden(system foreign)} exports a number of values expressing the basic
+C types:
+
address@hidden {Scheme Variable} float
address@hidden {Scheme Variable} double
address@hidden {Scheme Variable} int8
address@hidden {Scheme Variable} uint8
address@hidden {Scheme Variable} uint16
address@hidden {Scheme Variable} int16
address@hidden {Scheme Variable} uint32
address@hidden {Scheme Variable} int32
address@hidden {Scheme Variable} uint64
address@hidden {Scheme Variable} int64
+Values exported by the @code{(system foreign)} module, representing C
+numeric types of the specified sizes and signednesses.
address@hidden defvr
+
+In addition there are some convenience bindings for indicating types of
+platform-dependent size:
+
address@hidden {Scheme Variable} int
address@hidden {Scheme Variable} unsigned-int
address@hidden {Scheme Variable} long
address@hidden {Scheme Variable} unsigned-long
address@hidden {Scheme Variable} size_t
+Values exported by the @code{(system foreign)} module, representing C
+numeric types. For example, @code{long} may be @code{equal?} to
address@hidden on a 64-bit platform.
address@hidden defvr
+
address@hidden Foreign Variables
address@hidden Foreign Variables
+
+Given the types defined in the previous section, foreign values may be
+looked up dynamically using @code{dynamic-pointer}.
 
 @deffn {Scheme Procedure} dynamic-pointer name type dobj [len]
 @deffnx {C Function} scm_dynamic_pointer (name, type, dobj, len)
@@ -492,12 +518,179 @@ names in a program, you should @strong{not} include this 
underscore in
 @var{name} since it will be added automatically when necessary.
 @end deffn
 
+For example, currently Guile has a variable, @code{scm_numptob}, as part
+of its API. It is declared as a C @code{long}. So, to create a handle
+pointing to that foreign value, we do:
+
address@hidden
+(use-modules (system foreign))
+(define numptob (dynamic-pointer "scm_numptob" long (dynamic-link)))
+numptob
address@hidden #<foreign int32 8>
address@hidden example
+
address@hidden
+This example shows that a @code{long} on this platform is an
address@hidden, and that the value pointed to by @code{numptob} is 8.
+
address@hidden Foreign Pointers and Values
address@hidden Foreign Pointers and Values
+
+It's important at this point to conceptually separate foreign values
+from foreign pointers. @code{dynamic-pointer} gives you a foreign
+pointer. A foreign value is the semantic meaning of the bytes pointed to
+by a pointer. Only foreign pointers may be wrapped in Scheme. One may
+make a pointer to a foreign value, and wrap that as a Scheme object, but
+a bare foreign value may not be wrapped.
+
+When you call @code{dynamic-pointer}, the @var{type} argument indicates
+the type to which the given symbol points, but sometimes you don't know
+that type. Sometimes you have a pointer, and you don't know what kind of
+object it references. It's simply a pointer out into the ether, into the
address@hidden
+
+Guile can wrap such a pointer, by declaring that it points to
address@hidden
+
address@hidden {Scheme Variable} void
+A C type, used when wrapping C pointers. @code{void} represents the type
+to which the pointer points.
address@hidden defvr
+
+As an example, @code{(dynamic-pointer "foo" void bar-lib)} links in the
address@hidden symbol in the @var{bar-lib} library as a pointer to
address@hidden: a @code{void*}.
+
+Void pointers may be accessed as bytevectors.
+
address@hidden {Scheme Procedure} foreign->bytevector foreign [uvec_type 
[offset [len]]]
address@hidden {C Function} scm_foreign_to_bytevector foreign uvec_type offset 
len
+Return a bytevector aliasing the memory pointed to by
address@hidden
+
address@hidden must be a void pointer, a foreign whose type is
address@hidden By default, the resulting bytevector will alias
+all of the memory pointed to by @var{foreign}, from beginning
+to end, treated as a @code{vu8} array.
+
+The user may specify an alternate default interpretation for
+the memory by passing the @var{uvec_type} argument, to indicate
+that the memory is an array of elements of that type.
address@hidden should be something that
address@hidden would return, like @code{f32}
+or @code{s16}.
+
+Users may also specify that the bytevector should only alias a
+subset of the memory, by specifying @var{offset} and @var{len}
+arguments.
+
+Mutating the returned bytevector mutates the memory pointed to by
address@hidden, so buckle your seatbelts.
address@hidden deffn
+
address@hidden {Scheme Procedure} foreign-set! foreign val
address@hidden {C Function} scm_foreign_set_x foreign val
+Set the foreign value wrapped by @var{foreign}.
+
+The value will be set according to its type.
address@hidden deffn
+
+Typed pointers may be referenced using the @code{foreign-ref} and
address@hidden functions.
+
address@hidden {Scheme Procedure} foreign-ref foreign
address@hidden {C Function} scm_foreign_ref foreign
+Reference the foreign value wrapped by @var{foreign}.
+
+The value will be referenced according to its type.
+
address@hidden
+(foreign-ref numptob) @result{} 8 ; YMMV
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} foreign-set! foreign val
address@hidden {C Function} scm_foreign_set_x foreign val
+Set the foreign value wrapped by @var{foreign}.
+
+The value will be set according to its type.
+
address@hidden
+(foreign-set! numptob 120) ; Don't try this at home!
address@hidden example
address@hidden deffn
+
+If we wanted to corrupt Guile's internal state, we could set
address@hidden to another value; but we shouldn't, because that
+variable is not meant to be set. Indeed this point applies more widely:
+the C API is a dangerous place to be. Not only might setting a value
+crash your program, simply referencing a value with a wrong-sized type
+can prove equally disastrous.
+
 
 @node Dynamic FFI
 @subsection Dynamic FFI
 
+Of course, the land of C is not all nouns and no verbs: there are
+functions too, and Guile allows you to call them.
+
address@hidden {Scheme Procedure} make-foreign-function return_type func_ptr 
arg_types
address@hidden {C Procedure} scm_make_foreign_function return_type func_ptr 
arg_types
+Make a foreign function.
+
+Given the foreign void pointer @var{func_ptr}, its argument and
+return types @var{arg_types} and @var{return_type}, return a
+procedure that will pass arguments to the foreign function
+and return appropriate values.
+
address@hidden should be a list of foreign types.
address@hidden should be a foreign type.
address@hidden deffn
+
 TBD
 
address@hidden
+* Foreign Structs::
address@hidden menu
+
+
address@hidden Foreign Structs
address@hidden Foreign Structs
+
+Compared to Scheme, C is a lower-level language, but it does have the
+ability to compose types into structs and unions, so Guile must support
+these as well.
+
+Oftentimes one only accesses structures through pointers. In that case,
+it's easy to use void pointers and the bytevector interface to access
+structures. However C allows functions to accept and return structures
+and unions by value, on the stack, so it's necessary to be able to
+express structure and union types as Scheme values.
+
+Conventionally-packed st
+
+As yet, Guile only has support for conventionally-packed structs.
+tightly-packed structs and unions will
+
+Note that the Scheme values for C types are just that, @emph{values},
+not names. @code{(quote int64 uint8)} won't do what you want.
+
+C does not only have numeric types; one other type that it has is the
address@hidden, which in Guile is represented as a list of C types, so
+that the following two type declarations are equivalent:
+
address@hidden
+struct @{ int64_t foo; uint8_t bar; @}
+(list int64 uint8)
address@hidden example
+
+Putting Scheme types in a list is the same as declaring a struct type
+with the default packing. Guile does not currently support
+tightly-packed structs; in that case you should declare the value as
+being a void pointer, and access the bytes as a bytevector.
+
+
+
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End:
diff --git a/libguile/foreign.c b/libguile/foreign.c
index 0358d4f..06be7a5 100644
--- a/libguile/foreign.c
+++ b/libguile/foreign.c
@@ -634,7 +634,13 @@ fill_ffi_type (SCM type, ffi_type *ftype, ffi_type 
***type_ptrs,
     
 SCM_DEFINE (scm_make_foreign_function, "make-foreign-function", 3, 0, 0,
             (SCM return_type, SCM func_ptr, SCM arg_types),
-            "foo")
+            "Make a foreign function.\n\n"
+            "Given the foreign void pointer @var{func_ptr}, its argument and\n"
+            "return types @var{arg_types} and @var{return_type}, return a\n"
+            "procedure that will pass arguments to the foreign function\n"
+            "and return appropriate values.\n\n"
+            "@var{arg_types} should be a list of foreign types.\n"
+            "@code{return_type} should be a foreign type.")
 #define FUNC_NAME s_scm_make_foreign_function
 {
   SCM walk, scm_cif;


hooks/post-receive
-- 
GNU Guile




reply via email to

[Prev in Thread] Current Thread [Next in Thread]