mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
* doc/ref/api-foreign.texi (Void Pointers and Byte Access): Fix outdated function name: scm_foreign_to_bytevector to scm_pointer_to_bytevector.
972 lines
36 KiB
Text
972 lines
36 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2008,
|
|
@c 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@node Foreign Function Interface
|
|
@section Foreign Function Interface
|
|
@cindex foreign function interface
|
|
@cindex ffi
|
|
|
|
The more one hacks in Scheme, the more one realizes that there are
|
|
actually two computational worlds: one which is warm and alive, that
|
|
land of parentheses, and one cold and dead, the land of C and its ilk.
|
|
|
|
But yet we as programmers live in both worlds, and Guile itself is half
|
|
implemented in C. So it is that Guile's living half pays respect to its
|
|
dead counterpart, via a spectrum of interfaces to C ranging from dynamic
|
|
loading of Scheme primitives to dynamic binding of stock C library
|
|
procedures.
|
|
|
|
@menu
|
|
* Foreign Libraries:: Dynamically linking to libraries.
|
|
* 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 Pointers:: Accessing global variables.
|
|
* Dynamic FFI:: Calling arbitrary C functions.
|
|
@end menu
|
|
|
|
|
|
@node Foreign Libraries
|
|
@subsection Foreign Libraries
|
|
|
|
Most modern Unices have something called @dfn{shared libraries}. This
|
|
ordinarily means that they have the capability to share the executable
|
|
image of a library between several running programs to save memory and
|
|
disk space. But generally, shared libraries give a lot of additional
|
|
flexibility compared to the traditional static libraries. In fact,
|
|
calling them `dynamic' libraries is as correct as calling them `shared'.
|
|
|
|
Shared libraries really give you a lot of flexibility in addition to the
|
|
memory and disk space savings. When you link a program against a shared
|
|
library, that library is not closely incorporated into the final
|
|
executable. Instead, the executable of your program only contains
|
|
enough information to find the needed shared libraries when the program
|
|
is actually run. Only then, when the program is starting, is the final
|
|
step of the linking process performed. This means that you need not
|
|
recompile all programs when you install a new, only slightly modified
|
|
version of a shared library. The programs will pick up the changes
|
|
automatically the next time they are run.
|
|
|
|
Now, when all the necessary machinery is there to perform part of the
|
|
linking at run-time, why not take the next step and allow the programmer
|
|
to explicitly take advantage of it from within his program? Of course,
|
|
many operating systems that support shared libraries do just that, and
|
|
chances are that Guile will allow you to access this feature from within
|
|
your Scheme programs. As you might have guessed already, this feature
|
|
is called @dfn{dynamic linking}.@footnote{Some people also refer to the
|
|
final linking stage at program startup as `dynamic linking', so if you
|
|
want to make yourself perfectly clear, it is probably best to use the
|
|
more technical term @dfn{dlopening}, as suggested by Gordon Matzigkeit
|
|
in his libtool documentation.}
|
|
|
|
We titled this section ``foreign libraries'' because although the name
|
|
``foreign'' doesn't leak into the API, the world of C really is foreign
|
|
to Scheme -- and that estrangement extends to components of foreign
|
|
libraries as well, as we see in future sections.
|
|
|
|
@deffn {Scheme Procedure} dynamic-link [library]
|
|
@deffnx {C Function} scm_dynamic_link (library)
|
|
Find the shared library denoted by @var{library} (a string) and link it
|
|
into the running Guile application. When everything works out, return a
|
|
Scheme object suitable for representing the linked object file.
|
|
Otherwise an error is thrown. How object files are searched is system
|
|
dependent.
|
|
|
|
Normally, @var{library} is just the name of some shared library file
|
|
that will be searched for in the places where shared libraries usually
|
|
reside, such as in @file{/usr/lib} and @file{/usr/local/lib}.
|
|
|
|
@var{library} should not contain an extension such as @code{.so}. The
|
|
correct file name extension for the host operating system is provided
|
|
automatically, according to libltdl's rules (@pxref{Libltdl interface,
|
|
lt_dlopenext, @code{lt_dlopenext}, libtool, Shared Library Support for
|
|
GNU}).
|
|
|
|
When @var{library} is omitted, a @dfn{global symbol handle} is returned. This
|
|
handle provides access to the symbols available to the program at run-time,
|
|
including those exported by the program itself and the shared libraries already
|
|
loaded.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} dynamic-object? obj
|
|
@deffnx {C Function} scm_dynamic_object_p (obj)
|
|
Return @code{#t} if @var{obj} is a dynamic library handle, or @code{#f}
|
|
otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} dynamic-unlink dobj
|
|
@deffnx {C Function} scm_dynamic_unlink (dobj)
|
|
Unlink the indicated object file from the application. The
|
|
argument @var{dobj} must have been obtained by a call to
|
|
@code{dynamic-link}. After @code{dynamic-unlink} has been
|
|
called on @var{dobj}, its content is no longer accessible.
|
|
@end deffn
|
|
|
|
@smallexample
|
|
(define libgl-obj (dynamic-link "libGL"))
|
|
libgl-obj
|
|
@result{} #<dynamic-object "libGL">
|
|
(dynamic-unlink libGL-obj)
|
|
libGL-obj
|
|
@result{} #<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.
|
|
|
|
When dynamic linking is disabled or not supported on your system,
|
|
the above functions throw errors, but they are still available.
|
|
|
|
|
|
@node Foreign Functions
|
|
@subsection Foreign Functions
|
|
|
|
The most natural thing to do with a dynamic library is to grovel around
|
|
in it for a function pointer: a @dfn{foreign function}.
|
|
@code{dynamic-func} exists for that purpose.
|
|
|
|
@deffn {Scheme Procedure} dynamic-func name dobj
|
|
@deffnx {C Function} scm_dynamic_func (name, dobj)
|
|
Return a ``handle'' for the func @var{name} in the shared object referred to
|
|
by @var{dobj}. The handle can be passed to @code{dynamic-call} to
|
|
actually call the function.
|
|
|
|
Regardless whether your C compiler prepends an underscore @samp{_} to the global
|
|
names in a program, you should @strong{not} include this underscore in
|
|
@var{name} since it will be added automatically when necessary.
|
|
@end deffn
|
|
|
|
Guile has static support for calling functions with no arguments,
|
|
@code{dynamic-call}.
|
|
|
|
@deffn {Scheme Procedure} dynamic-call func dobj
|
|
@deffnx {C Function} scm_dynamic_call (func, dobj)
|
|
Call the C function indicated by @var{func} and @var{dobj}.
|
|
The function is passed no arguments and its return value is
|
|
ignored. When @var{function} is something returned by
|
|
@code{dynamic-func}, call that function and ignore @var{dobj}.
|
|
When @var{func} is a string , look it up in @var{dynobj}; this
|
|
is equivalent to
|
|
@smallexample
|
|
(dynamic-call (dynamic-func @var{func} @var{dobj}) #f)
|
|
@end smallexample
|
|
|
|
Interrupts are deferred while the C function is executing (with
|
|
@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}).
|
|
@end deffn
|
|
|
|
@code{dynamic-call} is not very powerful. It is mostly intended to be
|
|
used for calling specially written initialization functions that will
|
|
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-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
|
|
function. That function would add all the new types and primitives to
|
|
the Guile interpreter that it has to offer.
|
|
|
|
(There is actually another, better option: simply to create a
|
|
@file{libX11} wrapper in Scheme via the dynamic FFI. @xref{Dynamic FFI},
|
|
for more information.)
|
|
|
|
Given some set of C extensions to Guile, the next logical step is to
|
|
integrate these glue libraries into the module system of Guile so that
|
|
you can load new primitives into a running system just as you can load
|
|
new Scheme code.
|
|
|
|
@deffn {Scheme Procedure} load-extension lib init
|
|
@deffnx {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
|
|
|
|
@lisp
|
|
(dynamic-call INIT (dynamic-link LIB))
|
|
@end 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.
|
|
|
|
As for @code{dynamic-link}, @var{lib} should not contain any suffix such
|
|
as @code{.so} (@pxref{Foreign Libraries, dynamic-link}). 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
|
|
@file{libguile-bla-blum} for a extension related to a module @code{(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,
|
|
|
|
@lisp
|
|
(define-module (bla blum))
|
|
|
|
(load-extension "libguile-bla-blum" "bla_init_blum")
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@node C Extensions
|
|
@subsection C Extensions
|
|
|
|
The most interesting application of dynamically linked libraries is
|
|
probably to use them for providing @emph{compiled code modules} to
|
|
Scheme programs. As much fun as programming in Scheme is, every now and
|
|
then comes the need to write some low-level C stuff to make Scheme even
|
|
more fun.
|
|
|
|
Not only can you put these new primitives into their own module (see the
|
|
previous section), you can even put them into a shared library that is
|
|
only then linked to your running Guile image when it is actually
|
|
needed.
|
|
|
|
An example will hopefully make everything clear. Suppose we want to
|
|
make the Bessel functions of the C library available to Scheme in the
|
|
module @samp{(math bessel)}. First we need to write the appropriate
|
|
glue code to convert the arguments and return values of the functions
|
|
from Scheme to C and back. Additionally, we need a function that will
|
|
add them to the set of Guile primitives. Because this is just an
|
|
example, we will only implement this for the @code{j0} function.
|
|
|
|
@smallexample
|
|
#include <math.h>
|
|
#include <libguile.h>
|
|
|
|
SCM
|
|
j0_wrapper (SCM x)
|
|
@{
|
|
return scm_from_double (j0 (scm_to_double (x, "j0")));
|
|
@}
|
|
|
|
void
|
|
init_math_bessel ()
|
|
@{
|
|
scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
|
|
@}
|
|
@end smallexample
|
|
|
|
We can already try to bring this into action by manually calling the low
|
|
level functions for performing dynamic linking. The C source file needs
|
|
to be compiled into a shared library. Here is how to do it on
|
|
GNU/Linux, please refer to the @code{libtool} documentation for how to
|
|
create dynamically linkable libraries portably.
|
|
|
|
@smallexample
|
|
gcc -shared -o libbessel.so -fPIC bessel.c
|
|
@end smallexample
|
|
|
|
Now fire up Guile:
|
|
|
|
@lisp
|
|
(define bessel-lib (dynamic-link "./libbessel.so"))
|
|
(dynamic-call "init_math_bessel" bessel-lib)
|
|
(j0 2)
|
|
@result{} 0.223890779141236
|
|
@end lisp
|
|
|
|
The filename @file{./libbessel.so} should be pointing to the shared
|
|
library produced with the @code{gcc} command above, of course. The
|
|
second line of the Guile interaction will call the
|
|
@code{init_math_bessel} function which in turn will register the C
|
|
function @code{j0_wrapper} with the Guile interpreter under the name
|
|
@code{j0}. This function becomes immediately available and we can call
|
|
it from Scheme.
|
|
|
|
Fun, isn't it? But we are only half way there. This is what
|
|
@code{apropos} has to say about @code{j0}:
|
|
|
|
@smallexample
|
|
(apropos "j0")
|
|
@print{} (guile-user): j0 #<primitive-procedure j0>
|
|
@end smallexample
|
|
|
|
As you can see, @code{j0} is contained in the root module, where all
|
|
the other Guile primitives like @code{display}, etc live. In general,
|
|
a primitive is put into whatever module is the @dfn{current module} at
|
|
the time @code{scm_c_define_gsubr} is called.
|
|
|
|
A compiled module should have a specially named @dfn{module init
|
|
function}. Guile knows about this special name and will call that
|
|
function automatically after having linked in the shared library. For
|
|
our example, we replace @code{init_math_bessel} with the following code in
|
|
@file{bessel.c}:
|
|
|
|
@smallexample
|
|
void
|
|
init_math_bessel (void *unused)
|
|
@{
|
|
scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
|
|
scm_c_export ("j0", NULL);
|
|
@}
|
|
|
|
void
|
|
scm_init_math_bessel_module ()
|
|
@{
|
|
scm_c_define_module ("math bessel", init_math_bessel, NULL);
|
|
@}
|
|
@end smallexample
|
|
|
|
The general pattern for the name of a module init function is:
|
|
@samp{scm_init_}, followed by the name of the module where the
|
|
individual hierarchical components are concatenated with underscores,
|
|
followed by @samp{_module}.
|
|
|
|
After @file{libbessel.so} has been rebuilt, we need to place the shared
|
|
library into the right place.
|
|
|
|
Once the module has been correctly installed, it should be possible to
|
|
use it like this:
|
|
|
|
@smallexample
|
|
guile> (load-extension "./libbessel.so" "scm_init_math_bessel_module")
|
|
guile> (use-modules (math bessel))
|
|
guile> (j0 2)
|
|
0.223890779141236
|
|
guile> (apropos "j0")
|
|
@print{} (math bessel): j0 #<primitive-procedure j0>
|
|
@end smallexample
|
|
|
|
That's it!
|
|
|
|
|
|
@node Modules and Extensions
|
|
@subsection Modules and Extensions
|
|
|
|
The new primitives that you add to Guile with @code{scm_c_define_gsubr}
|
|
(@pxref{Primitive Procedures}) or with any of the other mechanisms are
|
|
placed into the module that is current when the
|
|
@code{scm_c_define_gsubr} is executed. Extensions loaded from the REPL,
|
|
for example, will be placed into the @code{(guile-user)} module, if the
|
|
REPL module was not changed.
|
|
|
|
To define C primitives within a specific module, the simplest way is:
|
|
|
|
@example
|
|
(define-module (foo bar))
|
|
(load-extension "foobar-c-code" "foo_bar_init")
|
|
@end example
|
|
|
|
@cindex extensiondir
|
|
When loaded with @code{(use-modules (foo bar))}, the
|
|
@code{load-extension} call looks for the @file{foobar-c-code.so} (etc)
|
|
object file in Guile's @code{extensiondir}, which is usually a
|
|
subdirectory of the @code{libdir}. For example, if your libdir is
|
|
@file{/usr/lib}, the @code{extensiondir} for the Guile @value{EFFECTIVE-VERSION}.@var{x}
|
|
series will be @file{/usr/lib/guile/@value{EFFECTIVE-VERSION}/}.
|
|
|
|
The extension path includes the major and minor version of Guile (the
|
|
``effective version''), because Guile guarantees compatibility within a
|
|
given effective version. This allows you to install different versions
|
|
of the same extension for different versions of Guile.
|
|
|
|
If the extension is not found in the @code{extensiondir}, Guile will
|
|
also search the standard system locations, such as @file{/usr/lib} or
|
|
@file{/usr/local/lib}. It is preferable, however, to keep your extension
|
|
out of the system library path, to prevent unintended interference with
|
|
other dynamically-linked C libraries.
|
|
|
|
If someone installs your module to a non-standard location then the
|
|
object file won't be found. You can address this by inserting the
|
|
install location in the @file{foo/bar.scm} file. This is convenient
|
|
for the user and also guarantees the intended object is read, even if
|
|
stray older or newer versions are in the loader's path.
|
|
|
|
The usual way to specify an install location is with a @code{prefix}
|
|
at the configure stage, for instance @samp{./configure prefix=/opt}
|
|
results in library files as say @file{/opt/lib/foobar-c-code.so}.
|
|
When using Autoconf (@pxref{Top, , Introduction, autoconf, The GNU
|
|
Autoconf Manual}), the library location is in a @code{libdir}
|
|
variable. Its value is intended to be expanded by @command{make}, and
|
|
can by substituted into a source file like @file{foo.scm.in}
|
|
|
|
@example
|
|
(define-module (foo bar))
|
|
(load-extension "XXextensiondirXX/foobar-c-code" "foo_bar_init")
|
|
@end example
|
|
|
|
@noindent
|
|
with the following in a @file{Makefile}, using @command{sed}
|
|
(@pxref{Top, , Introduction, sed, SED, A Stream Editor}),
|
|
|
|
@example
|
|
foo.scm: foo.scm.in
|
|
sed 's|XXextensiondirXX|$(libdir)/guile/@value{EFFECTIVE-VERSION}|' <foo.scm.in >foo.scm
|
|
@end example
|
|
|
|
The actual pattern @code{XXextensiondirXX} is arbitrary, it's only something
|
|
which doesn't otherwise occur. If several modules need the value, it
|
|
can be easier to create one @file{foo/config.scm} with a define of the
|
|
@code{extensiondir} location, and use that as required.
|
|
|
|
@example
|
|
(define-module (foo config))
|
|
(define-public foo-config-extensiondir "XXextensiondirXX"")
|
|
@end example
|
|
|
|
Such a file might have other locations too, for instance a data
|
|
directory for auxiliary files, or @code{localedir} if the module has
|
|
its own @code{gettext} message catalogue
|
|
(@pxref{Internationalization}).
|
|
|
|
It will be noted all of the above requires that the Scheme code to be
|
|
found in @code{%load-path} (@pxref{Load Paths}). Presently it's left up
|
|
to the system administrator or each user to augment that path when
|
|
installing Guile modules in non-default locations. But having reached
|
|
the Scheme code, that code should take care of hitting any of its own
|
|
private files etc.
|
|
|
|
|
|
@node Foreign Pointers
|
|
@subsection 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.
|
|
|
|
@menu
|
|
* Foreign Types:: Expressing C types in Scheme.
|
|
* Foreign Variables:: Pointers to C symbols.
|
|
* Void Pointers and Byte Access:: Pointers into the ether.
|
|
* Foreign Structs:: Packing and unpacking structs.
|
|
@end menu
|
|
|
|
@node Foreign Types
|
|
@subsubsection 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 describing a C function or a C structure so that it can be
|
|
accessed from Scheme, the data types of the parameters or fields must be
|
|
passed explicitly.
|
|
|
|
These ``C type values'' may be constructed using the constants and
|
|
procedures from the @code{(system foreign)} module, which may be loaded
|
|
like this:
|
|
|
|
@example
|
|
(use-modules (system foreign))
|
|
@end example
|
|
|
|
@code{(system foreign)} exports a number of values expressing the basic
|
|
C types:
|
|
|
|
@defvr {Scheme Variable} int8
|
|
@defvrx {Scheme Variable} uint8
|
|
@defvrx {Scheme Variable} uint16
|
|
@defvrx {Scheme Variable} int16
|
|
@defvrx {Scheme Variable} uint32
|
|
@defvrx {Scheme Variable} int32
|
|
@defvrx {Scheme Variable} uint64
|
|
@defvrx {Scheme Variable} int64
|
|
@defvrx {Scheme Variable} float
|
|
@defvrx {Scheme Variable} double
|
|
These values represent the C numeric types of the specified sizes and
|
|
signednesses.
|
|
@end defvr
|
|
|
|
In addition there are some convenience bindings for indicating types of
|
|
platform-dependent size:
|
|
|
|
@defvr {Scheme Variable} int
|
|
@defvrx {Scheme Variable} unsigned-int
|
|
@defvrx {Scheme Variable} long
|
|
@defvrx {Scheme Variable} unsigned-long
|
|
@defvrx {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
|
|
@code{int64} on a 64-bit platform.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} void
|
|
The @code{void} type. It can be used as the first argument to
|
|
@code{pointer->procedure} to wrap a C function that returns nothing.
|
|
@end defvr
|
|
|
|
In addition, the symbol @code{*} is used by convention to denote pointer
|
|
types. Procedures detailed in the following sections, such as
|
|
@code{pointer->procedure}, accept it as a type descriptor.
|
|
|
|
@node Foreign Variables
|
|
@subsubsection Foreign Variables
|
|
|
|
Pointers to variables in the current address space may be looked up
|
|
dynamically using @code{dynamic-pointer}.
|
|
|
|
@deffn {Scheme Procedure} dynamic-pointer name dobj
|
|
@deffnx {C Function} scm_dynamic_pointer (name, dobj)
|
|
Return a ``wrapped pointer'' for the symbol @var{name} in the shared
|
|
object referred to by @var{dobj}. The returned pointer points to a C
|
|
object.
|
|
|
|
Regardless whether your C compiler prepends an underscore @samp{_} to the global
|
|
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:
|
|
|
|
@example
|
|
(use-modules (system foreign))
|
|
(define numptob (dynamic-pointer "scm_numptob" (dynamic-link)))
|
|
numptob
|
|
@result{} #<pointer 0x7fb35b1b4688>
|
|
@end example
|
|
|
|
(The next section discusses ways to dereference pointers.)
|
|
|
|
A value returned by @code{dynamic-pointer} is a Scheme wrapper for a C
|
|
pointer.
|
|
|
|
@deffn {Scheme Procedure} pointer-address pointer
|
|
@deffnx {C Function} scm_pointer_address (pointer)
|
|
Return the numerical value of @var{pointer}.
|
|
|
|
@example
|
|
(pointer-address numptob)
|
|
@result{} 139984413364296 ; YMMV
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-pointer address [finalizer]
|
|
Return a foreign pointer object pointing to @var{address}. If
|
|
@var{finalizer} is passed, it should be a pointer to a one-argument C
|
|
function that will be called when the pointer object becomes
|
|
unreachable.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} pointer? obj
|
|
Return @code{#t} if @var{obj} is a pointer object, @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@defvr {Scheme Variable} %null-pointer
|
|
A foreign pointer whose value is 0.
|
|
@end defvr
|
|
|
|
@deffn {Scheme Procedure} null-pointer? pointer
|
|
Return @code{#t} if @var{pointer} is the null pointer, @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
For the purpose of passing SCM values directly to foreign functions, and
|
|
allowing them to return SCM values, Guile also supports some unsafe
|
|
casting operators.
|
|
|
|
@deffn {Scheme Procedure} scm->pointer scm
|
|
Return a foreign pointer object with the @code{object-address}
|
|
of @var{scm}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} pointer->scm pointer
|
|
Unsafely cast @var{pointer} to a Scheme object.
|
|
Cross your fingers!
|
|
@end deffn
|
|
|
|
|
|
@node Void Pointers and Byte Access
|
|
@subsubsection Void Pointers and Byte Access
|
|
|
|
Wrapped pointers are untyped, so they are essentially equivalent to C
|
|
@code{void} pointers. As in C, the memory region pointed to by a
|
|
pointer can be accessed at the byte level. This is achieved using
|
|
@emph{bytevectors} (@pxref{Bytevectors}). The @code{(rnrs bytevector)}
|
|
module contains procedures that can be used to convert byte sequences to
|
|
Scheme objects such as strings, floating point numbers, or integers.
|
|
|
|
@deffn {Scheme Procedure} pointer->bytevector pointer len [offset [uvec_type]]
|
|
@deffnx {C Function} scm_pointer_to_bytevector (pointer, len, offset, uvec_type)
|
|
Return a bytevector aliasing the @var{len} bytes pointed to by
|
|
@var{pointer}.
|
|
|
|
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.
|
|
@var{uvec_type} should be something that
|
|
@code{uniform-vector-element-type} would return, like @code{f32}
|
|
or @code{s16}.
|
|
|
|
When @var{offset} is passed, it specifies the offset in bytes relative
|
|
to @var{pointer} of the memory region aliased by the returned
|
|
bytevector.
|
|
|
|
Mutating the returned bytevector mutates the memory pointed to by
|
|
@var{pointer}, so buckle your seatbelts.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector->pointer bv [offset]
|
|
@deffnx {C Function} scm_bytevector_to_pointer (bv, offset)
|
|
Return a pointer pointer aliasing the memory pointed to by @var{bv} or
|
|
@var{offset} bytes after @var{bv} when @var{offset} is passed.
|
|
@end deffn
|
|
|
|
In addition to these primitives, convenience procedures are available:
|
|
|
|
@deffn {Scheme Procedure} dereference-pointer pointer
|
|
Assuming @var{pointer} points to a memory region that holds a pointer,
|
|
return this pointer.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string->pointer string [encoding]
|
|
Return a foreign pointer to a nul-terminated copy of @var{string} in the
|
|
given @var{encoding}, defaulting to the current locale encoding. The C
|
|
string is freed when the returned foreign pointer becomes unreachable.
|
|
|
|
This is the Scheme equivalent of @code{scm_to_stringn}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} pointer->string pointer [length] [encoding]
|
|
Return the string representing the C string pointed to by @var{pointer}.
|
|
If @var{length} is omitted or @code{-1}, the string is assumed to be
|
|
nul-terminated. Otherwise @var{length} is the number of bytes in memory
|
|
pointed to by @var{pointer}. The C string is assumed to be in the given
|
|
@var{encoding}, defaulting to the current locale encoding.
|
|
|
|
This is the Scheme equivalent of @code{scm_from_stringn}.
|
|
@end deffn
|
|
|
|
@cindex wrapped pointer types
|
|
Most object-oriented C libraries use pointers to specific data
|
|
structures to identify objects. It is useful in such cases to reify the
|
|
different pointer types as disjoint Scheme types. The
|
|
@code{define-wrapped-pointer-type} macro simplifies this.
|
|
|
|
@deffn {Scheme Syntax} define-wrapped-pointer-type type-name pred wrap unwrap print
|
|
Define helper procedures to wrap pointer objects into Scheme objects
|
|
with a disjoint type. Specifically, this macro defines:
|
|
|
|
@itemize
|
|
@item @var{pred}, a predicate for the new Scheme type;
|
|
@item @var{wrap}, a procedure that takes a pointer object and returns an
|
|
object that satisfies @var{pred};
|
|
@item @var{unwrap}, which does the reverse.
|
|
@end itemize
|
|
|
|
@var{wrap} preserves pointer identity, for two pointer objects @var{p1}
|
|
and @var{p2} that are @code{equal?}, @code{(eq? (@var{wrap} @var{p1})
|
|
(@var{wrap} @var{p2})) @result{} #t}.
|
|
|
|
Finally, @var{print} should name a user-defined procedure to print such
|
|
objects. The procedure is passed the wrapped object and a port to write
|
|
to.
|
|
|
|
For example, assume we are wrapping a C library that defines a type,
|
|
@code{bottle_t}, and functions that can be passed @code{bottle_t *}
|
|
pointers to manipulate them. We could write:
|
|
|
|
@example
|
|
(define-wrapped-pointer-type bottle
|
|
bottle?
|
|
wrap-bottle unwrap-bottle
|
|
(lambda (b p)
|
|
(format p "#<bottle of ~a ~x>"
|
|
(bottle-contents b)
|
|
(pointer-address (unwrap-bottle b)))))
|
|
|
|
(define grab-bottle
|
|
;; Wrapper for `bottle_t *grab (void)'.
|
|
(let ((grab (pointer->procedure '*
|
|
(dynamic-func "grab_bottle" libbottle)
|
|
'())))
|
|
(lambda ()
|
|
"Return a new bottle."
|
|
(wrap-bottle (grab)))))
|
|
|
|
(define bottle-contents
|
|
;; Wrapper for `const char *bottle_contents (bottle_t *)'.
|
|
(let ((contents (pointer->procedure '*
|
|
(dynamic-func "bottle_contents"
|
|
libbottle)
|
|
'(*))))
|
|
(lambda (b)
|
|
"Return the contents of B."
|
|
(pointer->string (contents (unwrap-bottle b))))))
|
|
|
|
(write (grab-bottle))
|
|
@result{} #<bottle of Ch@^ateau Haut-Brion 803d36>
|
|
@end example
|
|
|
|
In this example, @code{grab-bottle} is guaranteed to return a genuine
|
|
@code{bottle} object satisfying @code{bottle?}. Likewise,
|
|
@code{bottle-contents} errors out when its argument is not a genuine
|
|
@code{bottle} object.
|
|
@end deffn
|
|
|
|
Going back to the @code{scm_numptob} example above, here is how we can
|
|
read its value as a C @code{long} integer:
|
|
|
|
@example
|
|
(use-modules (rnrs bytevectors))
|
|
|
|
(bytevector-uint-ref (pointer->bytevector numptob (sizeof long))
|
|
0 (native-endianness)
|
|
(sizeof long))
|
|
@result{} 8
|
|
@end example
|
|
|
|
If we wanted to corrupt Guile's internal state, we could set
|
|
@code{scm_numptob} 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 accessing the data pointed to by a dangling
|
|
pointer or similar can prove equally disastrous.
|
|
|
|
@node Foreign Structs
|
|
@subsubsection Foreign Structs
|
|
|
|
Finally, one last note on foreign values before moving on to actually
|
|
calling foreign functions. Sometimes you need to deal with C structs,
|
|
which requires interpreting each element of the struct according to the
|
|
its type, offset, and alignment. Guile has some primitives to support
|
|
this.
|
|
|
|
@deffn {Scheme Procedure} sizeof type
|
|
@deffnx {C Function} scm_sizeof (type)
|
|
Return the size of @var{type}, in bytes.
|
|
|
|
@var{type} should be a valid C type, like @code{int}.
|
|
Alternately @var{type} may be the symbol @code{*}, in which
|
|
case the size of a pointer is returned. @var{type} may
|
|
also be a list of types, in which case the size of a
|
|
@code{struct} with ABI-conventional packing is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alignof type
|
|
@deffnx {C Function} scm_alignof (type)
|
|
Return the alignment of @var{type}, in bytes.
|
|
|
|
@var{type} should be a valid C type, like @code{int}.
|
|
Alternately @var{type} may be the symbol @code{*}, in which
|
|
case the alignment of a pointer is returned. @var{type} may
|
|
also be a list of types, in which case the alignment of a
|
|
@code{struct} with ABI-conventional packing is returned.
|
|
@end deffn
|
|
|
|
Guile also provides some convenience methods to pack and unpack foreign
|
|
pointers wrapping C structs.
|
|
|
|
@deffn {Scheme Procedure} make-c-struct types vals
|
|
Create a foreign pointer to a C struct containing @var{vals} with types
|
|
@code{types}.
|
|
|
|
@var{vals} and @code{types} should be lists of the same length.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} parse-c-struct foreign types
|
|
Parse a foreign pointer to a C struct, returning a list of values.
|
|
|
|
@code{types} should be a list of C types.
|
|
@end deffn
|
|
|
|
For example, to create and parse the equivalent of a @code{struct @{
|
|
int64_t a; uint8_t b; @}}:
|
|
|
|
@example
|
|
(parse-c-struct (make-c-struct (list int64 uint8)
|
|
(list 300 43))
|
|
(list int64 uint8))
|
|
@result{} (300 43)
|
|
@end example
|
|
|
|
As yet, Guile only has convenience routines to support
|
|
conventionally-packed structs. But given the @code{bytevector->foreign}
|
|
and @code{foreign->bytevector} routines, one can create and parse
|
|
tightly packed structs and unions by hand. See the code for
|
|
@code{(system foreign)} for details.
|
|
|
|
|
|
@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.
|
|
|
|
@deffn {Scheme Procedure} pointer->procedure return_type func_ptr arg_types
|
|
@deffnx {C Procedure} scm_pointer_to_procedure (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.
|
|
|
|
@var{arg_types} should be a list of foreign types.
|
|
@code{return_type} should be a foreign type. @xref{Foreign Types}, for
|
|
more information on foreign types.
|
|
@end deffn
|
|
|
|
Here is a better definition of @code{(math bessel)}:
|
|
|
|
@example
|
|
(define-module (math bessel)
|
|
#:use-module (system foreign)
|
|
#:export (j0))
|
|
|
|
(define libm (dynamic-link "libm"))
|
|
|
|
(define j0
|
|
(pointer->procedure double
|
|
(dynamic-func "j0" libm)
|
|
(list double)))
|
|
@end example
|
|
|
|
That's it! No C at all.
|
|
|
|
Numeric arguments and return values from foreign functions are
|
|
represented as Scheme values. For example, @code{j0} in the above
|
|
example takes a Scheme number as its argument, and returns a Scheme
|
|
number.
|
|
|
|
Pointers may be passed to and returned from foreign functions as well.
|
|
In that case the type of the argument or return value should be the
|
|
symbol @code{*}, indicating a pointer. For example, the following
|
|
code makes @code{memcpy} available to Scheme:
|
|
|
|
@example
|
|
(define memcpy
|
|
(let ((this (dynamic-link)))
|
|
(pointer->procedure '*
|
|
(dynamic-func "memcpy" this)
|
|
(list '* '* size_t))))
|
|
@end example
|
|
|
|
To invoke @code{memcpy}, one must pass it foreign pointers:
|
|
|
|
@example
|
|
(use-modules (rnrs bytevectors))
|
|
|
|
(define src-bits
|
|
(u8-list->bytevector '(0 1 2 3 4 5 6 7)))
|
|
(define src
|
|
(bytevector->pointer src-bits))
|
|
(define dest
|
|
(bytevector->pointer (make-bytevector 16 0)))
|
|
|
|
(memcpy dest src (bytevector-length src-bits))
|
|
|
|
(bytevector->u8-list (pointer->bytevector dest 16))
|
|
@result{} (0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0)
|
|
@end example
|
|
|
|
One may also pass structs as values, passing structs as foreign
|
|
pointers. @xref{Foreign Structs}, for more information on how to express
|
|
struct types and struct values.
|
|
|
|
``Out'' arguments are passed as foreign pointers. The memory pointed to
|
|
by the foreign pointer is mutated in place.
|
|
|
|
@example
|
|
;; struct timeval @{
|
|
;; time_t tv_sec; /* seconds */
|
|
;; suseconds_t tv_usec; /* microseconds */
|
|
;; @};
|
|
;; assuming fields are of type "long"
|
|
|
|
(define gettimeofday
|
|
(let ((f (pointer->procedure
|
|
int
|
|
(dynamic-func "gettimeofday" (dynamic-link))
|
|
(list '* '*)))
|
|
(tv-type (list long long)))
|
|
(lambda ()
|
|
(let* ((timeval (make-c-struct tv-type (list 0 0)))
|
|
(ret (f timeval %null-pointer)))
|
|
(if (zero? ret)
|
|
(apply values (parse-c-struct timeval tv-type))
|
|
(error "gettimeofday returned an error" ret))))))
|
|
|
|
(gettimeofday)
|
|
@result{} 1270587589
|
|
@result{} 499553
|
|
@end example
|
|
|
|
As you can see, this interface to foreign functions is at a very low,
|
|
somewhat dangerous level@footnote{A contribution to Guile in the form of
|
|
a high-level FFI would be most welcome.}.
|
|
|
|
@cindex callbacks
|
|
The FFI can also work in the opposite direction: making Scheme
|
|
procedures callable from C. This makes it possible to use Scheme
|
|
procedures as ``callbacks'' expected by C function.
|
|
|
|
@deffn {Scheme Procedure} procedure->pointer return-type proc arg-types
|
|
@deffnx {C Function} scm_procedure_to_pointer (return_type, proc, arg_types)
|
|
Return a pointer to a C function of type @var{return-type}
|
|
taking arguments of types @var{arg-types} (a list) and
|
|
behaving as a proxy to procedure @var{proc}. Thus
|
|
@var{proc}'s arity, supported argument types, and return
|
|
type should match @var{return-type} and @var{arg-types}.
|
|
@end deffn
|
|
|
|
As an example, here's how the C library's @code{qsort} array sorting
|
|
function can be made accessible to Scheme (@pxref{Array Sort Function,
|
|
@code{qsort},, libc, The GNU C Library Reference Manual}):
|
|
|
|
@example
|
|
(define qsort!
|
|
(let ((qsort (pointer->procedure void
|
|
(dynamic-func "qsort"
|
|
(dynamic-link))
|
|
(list '* size_t size_t '*))))
|
|
(lambda (bv compare)
|
|
;; Sort bytevector BV in-place according to comparison
|
|
;; procedure COMPARE.
|
|
(let ((ptr (procedure->pointer int
|
|
(lambda (x y)
|
|
;; X and Y are pointers so,
|
|
;; for convenience, dereference
|
|
;; them before calling COMPARE.
|
|
(compare (dereference-uint8* x)
|
|
(dereference-uint8* y)))
|
|
(list '* '*))))
|
|
(qsort (bytevector->pointer bv)
|
|
(bytevector-length bv) 1 ;; we're sorting bytes
|
|
ptr)))))
|
|
|
|
(define (dereference-uint8* ptr)
|
|
;; Helper function: dereference the byte pointed to by PTR.
|
|
(let ((b (pointer->bytevector ptr 1)))
|
|
(bytevector-u8-ref b 0)))
|
|
|
|
(define bv
|
|
;; An unsorted array of bytes.
|
|
(u8-list->bytevector '(7 1 127 3 5 4 77 2 9 0)))
|
|
|
|
;; Sort BV.
|
|
(qsort! bv (lambda (x y) (- x y)))
|
|
|
|
;; Let's see what the sorted array looks like:
|
|
(bytevector->u8-list bv)
|
|
@result{} (0 1 2 3 4 5 7 9 77 127)
|
|
@end example
|
|
|
|
And voil@`a!
|
|
|
|
Note that @code{procedure->pointer} is not supported (and not defined)
|
|
on a few exotic architectures. Thus, user code may need to check
|
|
@code{(defined? 'procedure->pointer)}. Nevertheless, it is available on
|
|
many architectures, including (as of libffi 3.0.9) x86, ia64, SPARC,
|
|
PowerPC, ARM, and MIPS, to name a few.
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|