mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
add api-foreign.texi
* doc/ref/api-foreign.texi: New file. * doc/ref/api-modules.texi: Reorganize bits about dynamic linking into api-foreign. * doc/ref/guile.texi: * doc/ref/Makefile.am: Adapt to api-foreign.texi.
This commit is contained in:
parent
7b702b5391
commit
726b8ba3fd
4 changed files with 686 additions and 652 deletions
|
@ -40,6 +40,7 @@ guile_TEXINFOS = preface.texi \
|
||||||
api-binding.texi \
|
api-binding.texi \
|
||||||
api-control.texi \
|
api-control.texi \
|
||||||
api-io.texi \
|
api-io.texi \
|
||||||
|
api-foreign.texi \
|
||||||
api-lalr.texi \
|
api-lalr.texi \
|
||||||
api-evaluation.texi \
|
api-evaluation.texi \
|
||||||
api-memory.texi \
|
api-memory.texi \
|
||||||
|
|
512
doc/ref/api-foreign.texi
Normal file
512
doc/ref/api-foreign.texi
Normal file
|
@ -0,0 +1,512 @@
|
||||||
|
@c -*-texinfo-*-
|
||||||
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010
|
||||||
|
@c Free Software Foundation, Inc.
|
||||||
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@page
|
||||||
|
@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
|
||||||
|
prodedures.
|
||||||
|
|
||||||
|
@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 Values:: Accessing global variables.
|
||||||
|
* Dynamic FFI:: Fu.
|
||||||
|
@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}.
|
||||||
|
|
||||||
|
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 libc-obj (dynamic-link "libc.so"))
|
||||||
|
libc-obj
|
||||||
|
@result{} #<dynamic-object "libc.so">
|
||||||
|
(dynamic-args-call 'rand libc-obj '())
|
||||||
|
@result{} 269167349
|
||||||
|
(dynamic-unlink libc-obj)
|
||||||
|
libc-obj
|
||||||
|
@result{} #<dynamic-object "libc.so" (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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} dynamic-args-call func dobj args
|
||||||
|
@deffnx {C Function} scm_dynamic_args_call (func, dobj, args)
|
||||||
|
Call the C function indicated by @var{func} and @var{dobj},
|
||||||
|
just like @code{dynamic-call}, but pass it some arguments and
|
||||||
|
return its return value. The C function is expected to take
|
||||||
|
two arguments and return an @code{int}, just like @code{main}:
|
||||||
|
@smallexample
|
||||||
|
int c_func (int argc, char **argv);
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The parameter @var{args} must be a list of strings and is
|
||||||
|
converted into an array of @code{char *}. The array is passed
|
||||||
|
in @var{argv} and its size in @var{argc}. The return value is
|
||||||
|
converted to a Scheme number and returned from the call to
|
||||||
|
@code{dynamic-args-call}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
The functions to call a function from a dynamically linked library,
|
||||||
|
@code{dynamic-call} and @code{dynamic-args-call}, are not very powerful.
|
||||||
|
They are 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} and
|
||||||
|
@code{dynamic-args-call}. Instead, the usual way would be to write a
|
||||||
|
special Guile<->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.
|
||||||
|
|
||||||
|
From this setup 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.
|
||||||
|
|
||||||
|
[foreshadowing regarding dynamic ffi]
|
||||||
|
|
||||||
|
@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.
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
@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!
|
||||||
|
|
||||||
|
@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.
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-module (bla blum))
|
||||||
|
|
||||||
|
(load-extension "libguile-bla-blum" "bla_init_blum")
|
||||||
|
@end lisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
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 the standard system locations, such as @file{/usr/lib}
|
||||||
|
or @file{/usr/local/lib}.
|
||||||
|
|
||||||
|
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 "XXlibdirXX/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|XXlibdirXX|$(libdir)|' <foo.scm.in >foo.scm
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The actual pattern @code{XXlibdirXX} 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{libdir} location, and use that as required.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define-module (foo config))
|
||||||
|
(define-public foo-config-libdir "XXlibdirXX"")
|
||||||
|
@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}).
|
||||||
|
|
||||||
|
When installing multiple C code objects, it can be convenient to put
|
||||||
|
them in a subdirectory of @code{libdir}, thus giving for example
|
||||||
|
@code{/usr/lib/foo/some-obj.so}. If the objects are only meant to be
|
||||||
|
used through the module, then a subdirectory keeps them out of sight.
|
||||||
|
|
||||||
|
It will be noted all of the above requires that the Scheme code to be
|
||||||
|
found in @code{%load-path} (@pxref{Build Config}). 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.
|
||||||
|
|
||||||
|
Presently there's no convention for having a Guile version number in
|
||||||
|
module C code filenames or directories. This is primarily because
|
||||||
|
there's no established principles for two versions of Guile to be
|
||||||
|
installed under the same prefix (eg. two both under @file{/usr}).
|
||||||
|
Assuming upward compatibility is maintained then this should be
|
||||||
|
unnecessary, and if compatibility is not maintained then it's highly
|
||||||
|
likely a package will need to be revisited anyway.
|
||||||
|
|
||||||
|
The present suggestion is that modules should assume when they're
|
||||||
|
installed under a particular @code{prefix} that there's a single
|
||||||
|
version of Guile there, and the @code{guile-config} at build time has
|
||||||
|
the necessary information about it. C code or Scheme code might adapt
|
||||||
|
itself accordingly (allowing for features not available in an older
|
||||||
|
version for instance).
|
||||||
|
|
||||||
|
|
||||||
|
@node Foreign Values
|
||||||
|
@subsection Foreign Values
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} dynamic-pointer name type dobj [len]
|
||||||
|
@deffnx {C Function} scm_dynamic_pointer (name, type, dobj, len)
|
||||||
|
Return a ``handle'' for the pointer @var{name} in the shared object referred to
|
||||||
|
by @var{dobj}. The handle aliases a C value, and is declared to be of type
|
||||||
|
@var{type}. Valid types are defined in the @code{(system foreign)} module.
|
||||||
|
|
||||||
|
This facility works by asking the dynamic linker for the address of a symbol,
|
||||||
|
then assuming that it aliases a value of a given type. Obviously, the user must
|
||||||
|
be very careful to ensure that the value actually is of the declared type, or
|
||||||
|
bad things will happen.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@node Dynamic FFI
|
||||||
|
@subsection Dynamic FFI
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
|
@ -41,122 +41,21 @@ clutter the global name space.
|
||||||
In addition, Guile offers variables as first-class objects. They can
|
In addition, Guile offers variables as first-class objects. They can
|
||||||
be used for interacting with the module system.
|
be used for interacting with the module system.
|
||||||
|
|
||||||
@menu
|
|
||||||
* provide and require:: The SLIB feature mechanism.
|
|
||||||
* Environments:: R5RS top-level environments.
|
|
||||||
* The Guile module system:: How Guile does it.
|
|
||||||
* Dynamic Libraries:: Loading libraries of compiled code at run time.
|
|
||||||
* Variables:: First-class variables.
|
|
||||||
@end menu
|
|
||||||
|
|
||||||
@node provide and require
|
|
||||||
@subsection provide and require
|
|
||||||
|
|
||||||
Aubrey Jaffer, mostly to support his portable Scheme library SLIB,
|
|
||||||
implemented a provide/require mechanism for many Scheme implementations.
|
|
||||||
Library files in SLIB @emph{provide} a feature, and when user programs
|
|
||||||
@emph{require} that feature, the library file is loaded in.
|
|
||||||
|
|
||||||
For example, the file @file{random.scm} in the SLIB package contains the
|
|
||||||
line
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(provide 'random)
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
so to use its procedures, a user would type
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(require 'random)
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
and they would magically become available, @emph{but still have the same
|
|
||||||
names!} So this method is nice, but not as good as a full-featured
|
|
||||||
module system.
|
|
||||||
|
|
||||||
When SLIB is used with Guile, provide and require can be used to access
|
|
||||||
its facilities.
|
|
||||||
|
|
||||||
@node Environments
|
|
||||||
@subsection Environments
|
|
||||||
@cindex environment
|
|
||||||
|
|
||||||
Scheme, as defined in R5RS, does @emph{not} have a full module system.
|
|
||||||
However it does define the concept of a top-level @dfn{environment}.
|
|
||||||
Such an environment maps identifiers (symbols) to Scheme objects such
|
|
||||||
as procedures and lists: @ref{About Closure}. In other words, it
|
|
||||||
implements a set of @dfn{bindings}.
|
|
||||||
|
|
||||||
Environments in R5RS can be passed as the second argument to
|
|
||||||
@code{eval} (@pxref{Fly Evaluation}). Three procedures are defined to
|
|
||||||
return environments: @code{scheme-report-environment},
|
|
||||||
@code{null-environment} and @code{interaction-environment} (@pxref{Fly
|
|
||||||
Evaluation}).
|
|
||||||
|
|
||||||
In addition, in Guile any module can be used as an R5RS environment,
|
|
||||||
i.e., passed as the second argument to @code{eval}.
|
|
||||||
|
|
||||||
Note: the following two procedures are available only when the
|
|
||||||
@code{(ice-9 r5rs)} module is loaded:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(use-modules (ice-9 r5rs))
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} scheme-report-environment version
|
|
||||||
@deffnx {Scheme Procedure} null-environment version
|
|
||||||
@var{version} must be the exact integer `5', corresponding to revision
|
|
||||||
5 of the Scheme report (the Revised^5 Report on Scheme).
|
|
||||||
@code{scheme-report-environment} returns a specifier for an
|
|
||||||
environment that is empty except for all bindings defined in the
|
|
||||||
report that are either required or both optional and supported by the
|
|
||||||
implementation. @code{null-environment} returns a specifier for an
|
|
||||||
environment that is empty except for the (syntactic) bindings for all
|
|
||||||
syntactic keywords defined in the report that are either required or
|
|
||||||
both optional and supported by the implementation.
|
|
||||||
|
|
||||||
Currently Guile does not support values of @var{version} for other
|
|
||||||
revisions of the report.
|
|
||||||
|
|
||||||
The effect of assigning (through the use of @code{eval}) a variable
|
|
||||||
bound in a @code{scheme-report-environment} (for example @code{car})
|
|
||||||
is unspecified. Currently the environments specified by
|
|
||||||
@code{scheme-report-environment} are not immutable in Guile.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@node The Guile module system
|
|
||||||
@subsection The Guile module system
|
|
||||||
|
|
||||||
The Guile module system extends the concept of environments, discussed
|
|
||||||
in the previous section, with mechanisms to define, use and customise
|
|
||||||
sets of bindings.
|
|
||||||
|
|
||||||
In 1996 Tom Lord implemented a full-featured module system for Guile which
|
|
||||||
allows loading Scheme source files into a private name space. This system has
|
|
||||||
been available since at least Guile version 1.1.
|
|
||||||
|
|
||||||
For Guile version 1.5.0 and later, the system has been improved to have better
|
|
||||||
integration from C code, more fine-grained user control over interfaces, and
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
Although it is anticipated that the module system implementation will
|
|
||||||
change in the future, the Scheme programming interface described in this
|
|
||||||
manual should be considered stable. The C programming interface is
|
|
||||||
considered relatively stable, although at the time of this writing,
|
|
||||||
there is still some flux.
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* General Information about Modules:: Guile module basics.
|
* General Information about Modules:: Guile module basics.
|
||||||
* Using Guile Modules:: How to use existing modules.
|
* Using Guile Modules:: How to use existing modules.
|
||||||
* Creating Guile Modules:: How to package your code into modules.
|
* Creating Guile Modules:: How to package your code into modules.
|
||||||
* Module System Reflection:: Accessing module objects at run-time.
|
* Module System Reflection:: Accessing module objects at run-time.
|
||||||
* Included Guile Modules:: Which modules come with Guile?
|
* Included Guile Modules:: Which modules come with Guile?
|
||||||
* Accessing Modules from C:: How to work with modules with C code.
|
|
||||||
* R6RS Version References:: Using version numbers with modules.
|
* R6RS Version References:: Using version numbers with modules.
|
||||||
|
* Accessing Modules from C:: How to work with modules with C code.
|
||||||
|
* Variables:: First-class variables.
|
||||||
|
* provide and require:: The SLIB feature mechanism.
|
||||||
|
* Environments:: R5RS top-level environments.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node General Information about Modules
|
@node General Information about Modules
|
||||||
@subsubsection General Information about Modules
|
@subsection General Information about Modules
|
||||||
|
|
||||||
A Guile module can be thought of as a collection of named procedures,
|
A Guile module can be thought of as a collection of named procedures,
|
||||||
variables and macros. More precisely, it is a set of @dfn{bindings}
|
variables and macros. More precisely, it is a set of @dfn{bindings}
|
||||||
|
@ -220,7 +119,7 @@ definition option (@pxref{Creating Guile Modules}).
|
||||||
|
|
||||||
|
|
||||||
@node Using Guile Modules
|
@node Using Guile Modules
|
||||||
@subsubsection Using Guile Modules
|
@subsection Using Guile Modules
|
||||||
|
|
||||||
To use a Guile module is to access either its public interface or a
|
To use a Guile module is to access either its public interface or a
|
||||||
custom interface (@pxref{General Information about Modules}). Both
|
custom interface (@pxref{General Information about Modules}). Both
|
||||||
|
@ -376,7 +275,7 @@ last resort.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node Creating Guile Modules
|
@node Creating Guile Modules
|
||||||
@subsubsection Creating Guile Modules
|
@subsection Creating Guile Modules
|
||||||
|
|
||||||
When you want to create your own modules, you have to take the following
|
When you want to create your own modules, you have to take the following
|
||||||
steps:
|
steps:
|
||||||
|
@ -618,7 +517,7 @@ imported by the current module from some other module.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node Module System Reflection
|
@node Module System Reflection
|
||||||
@subsubsection Module System Reflection
|
@subsection Module System Reflection
|
||||||
|
|
||||||
The previous sections have described a declarative view of the module
|
The previous sections have described a declarative view of the module
|
||||||
system. You can also work with it programmatically by accessing and
|
system. You can also work with it programmatically by accessing and
|
||||||
|
@ -673,7 +572,7 @@ likely be a module returned by @code{resolve-interface}.
|
||||||
|
|
||||||
|
|
||||||
@node Included Guile Modules
|
@node Included Guile Modules
|
||||||
@subsubsection Included Guile Modules
|
@subsection Included Guile Modules
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
@c FIXME::martin: Review me!
|
||||||
|
|
||||||
|
@ -796,8 +695,92 @@ library SLIB from Guile (@pxref{SLIB}).
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node R6RS Version References
|
||||||
|
@subsection R6RS Version References
|
||||||
|
|
||||||
|
Guile's module system includes support for locating modules based on
|
||||||
|
a declared version specifier of the same form as the one described in
|
||||||
|
R6RS (@pxref{Library form, R6RS Library Form,, r6rs, The Revised^6
|
||||||
|
Report on the Algorithmic Language Scheme}). By using the
|
||||||
|
@code{#:version} keyword in a @code{define-module} form, a module may
|
||||||
|
specify a version as a list of zero or more exact, nonnegative integers.
|
||||||
|
|
||||||
|
This version can then be used to locate the module during the module
|
||||||
|
search process. Client modules and callers of the @code{use-modules}
|
||||||
|
function may specify constraints on the versions of target modules by
|
||||||
|
providing a @dfn{version reference}, which has one of the following
|
||||||
|
forms:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(@var{sub-version-reference} ...)
|
||||||
|
(and @var{version-reference} ...)
|
||||||
|
(or @var{version-reference} ...)
|
||||||
|
(not @var{version-reference})
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
in which @var{sub-version-reference} is in turn one of:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(@var{sub-version})
|
||||||
|
(>= @var{sub-version})
|
||||||
|
(<= @var{sub-version})
|
||||||
|
(and @var{sub-version-reference} ...)
|
||||||
|
(or @var{sub-version-reference} ...)
|
||||||
|
(not @var{sub-version-reference})
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
in which @var{sub-version} is an exact, nonnegative integer as above. A
|
||||||
|
version reference matches a declared module version if each element of
|
||||||
|
the version reference matches a corresponding element of the module
|
||||||
|
version, according to the following rules:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
The @code{and} sub-form matches a version or version element if every
|
||||||
|
element in the tail of the sub-form matches the specified version or
|
||||||
|
version element.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The @code{or} sub-form matches a version or version element if any
|
||||||
|
element in the tail of the sub-form matches the specified version or
|
||||||
|
version element.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The @code{not} sub-form matches a version or version element if the tail
|
||||||
|
of the sub-form does not match the version or version element.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The @code{>=} sub-form matches a version element if the element is
|
||||||
|
greater than or equal to the @var{sub-version} in the tail of the
|
||||||
|
sub-form.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The @code{<=} sub-form matches a version element if the version is less
|
||||||
|
than or equal to the @var{sub-version} in the tail of the sub-form.
|
||||||
|
|
||||||
|
@item
|
||||||
|
A @var{sub-version} matches a version element if one is @var{eqv?} to
|
||||||
|
the other.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
For example, a module declared as:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-module (mylib mymodule) #:version (1 2 0))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
would be successfully loaded by any of the following @code{use-modules}
|
||||||
|
expressions:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(use-modules ((mylib mymodule) #:version (1 2 (>= 0))))
|
||||||
|
(use-modules ((mylib mymodule) #:version (or (1 2 0) (1 2 1))))
|
||||||
|
(use-modules ((mylib mymodule) #:version ((and (>= 1) (not 2)) 2 0)))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
|
||||||
@node Accessing Modules from C
|
@node Accessing Modules from C
|
||||||
@subsubsection Accessing Modules from C
|
@subsection Accessing Modules from C
|
||||||
|
|
||||||
The last sections have described how modules are used in Scheme code,
|
The last sections have described how modules are used in Scheme code,
|
||||||
which is the recommended way of creating and accessing modules. You
|
which is the recommended way of creating and accessing modules. You
|
||||||
|
@ -894,544 +877,6 @@ of the current module. The list of names is terminated by
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
@node R6RS Version References
|
|
||||||
@subsubsection R6RS Version References
|
|
||||||
|
|
||||||
Guile's module system includes support for locating modules based on
|
|
||||||
a declared version specifier of the same form as the one described in
|
|
||||||
R6RS (@pxref{Library form, R6RS Library Form,, r6rs, The Revised^6
|
|
||||||
Report on the Algorithmic Language Scheme}). By using the
|
|
||||||
@code{#:version} keyword in a @code{define-module} form, a module may
|
|
||||||
specify a version as a list of zero or more exact, nonnegative integers.
|
|
||||||
|
|
||||||
This version can then be used to locate the module during the module
|
|
||||||
search process. Client modules and callers of the @code{use-modules}
|
|
||||||
function may specify constraints on the versions of target modules by
|
|
||||||
providing a @dfn{version reference}, which has one of the following
|
|
||||||
forms:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(@var{sub-version-reference} ...)
|
|
||||||
(and @var{version-reference} ...)
|
|
||||||
(or @var{version-reference} ...)
|
|
||||||
(not @var{version-reference})
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
in which @var{sub-version-reference} is in turn one of:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(@var{sub-version})
|
|
||||||
(>= @var{sub-version})
|
|
||||||
(<= @var{sub-version})
|
|
||||||
(and @var{sub-version-reference} ...)
|
|
||||||
(or @var{sub-version-reference} ...)
|
|
||||||
(not @var{sub-version-reference})
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
in which @var{sub-version} is an exact, nonnegative integer as above. A
|
|
||||||
version reference matches a declared module version if each element of
|
|
||||||
the version reference matches a corresponding element of the module
|
|
||||||
version, according to the following rules:
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
@item
|
|
||||||
The @code{and} sub-form matches a version or version element if every
|
|
||||||
element in the tail of the sub-form matches the specified version or
|
|
||||||
version element.
|
|
||||||
|
|
||||||
@item
|
|
||||||
The @code{or} sub-form matches a version or version element if any
|
|
||||||
element in the tail of the sub-form matches the specified version or
|
|
||||||
version element.
|
|
||||||
|
|
||||||
@item
|
|
||||||
The @code{not} sub-form matches a version or version element if the tail
|
|
||||||
of the sub-form does not match the version or version element.
|
|
||||||
|
|
||||||
@item
|
|
||||||
The @code{>=} sub-form matches a version element if the element is
|
|
||||||
greater than or equal to the @var{sub-version} in the tail of the
|
|
||||||
sub-form.
|
|
||||||
|
|
||||||
@item
|
|
||||||
The @code{<=} sub-form matches a version element if the version is less
|
|
||||||
than or equal to the @var{sub-version} in the tail of the sub-form.
|
|
||||||
|
|
||||||
@item
|
|
||||||
A @var{sub-version} matches a version element if one is @var{eqv?} to
|
|
||||||
the other.
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
For example, a module declared as:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(define-module (mylib mymodule) #:version (1 2 0))
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
would be successfully loaded by any of the following @code{use-modules}
|
|
||||||
expressions:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(use-modules ((mylib mymodule) #:version (1 2 (>= 0))))
|
|
||||||
(use-modules ((mylib mymodule) #:version (or (1 2 0) (1 2 1))))
|
|
||||||
(use-modules ((mylib mymodule) #:version ((and (>= 1) (not 2)) 2 0)))
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
|
|
||||||
@node Dynamic Libraries
|
|
||||||
@subsection Dynamic 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.}
|
|
||||||
|
|
||||||
As with many aspects of Guile, there is a low-level way to access the
|
|
||||||
dynamic linking apparatus, and a more high-level interface that
|
|
||||||
integrates dynamically linked libraries into the module system.
|
|
||||||
|
|
||||||
@menu
|
|
||||||
* Low level dynamic linking::
|
|
||||||
* Compiled Code Modules::
|
|
||||||
* Dynamic Linking and Compiled Code Modules::
|
|
||||||
* Compiled Code Installation::
|
|
||||||
@end menu
|
|
||||||
|
|
||||||
@node Low level dynamic linking
|
|
||||||
@subsubsection Low level dynamic linking
|
|
||||||
|
|
||||||
When using the low level procedures to do your dynamic linking, you have
|
|
||||||
complete control over which library is loaded when and what gets done
|
|
||||||
with it.
|
|
||||||
|
|
||||||
@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}.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} dynamic-func name dobj
|
|
||||||
@deffnx {C Function} scm_dynamic_func (name, dobj)
|
|
||||||
Search the dynamic object @var{dobj} for the C function
|
|
||||||
indicated by the string @var{name} and return some Scheme
|
|
||||||
handle that can later be used with @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{function}. Guile knows whether the underscore is
|
|
||||||
needed or not and will add it when necessary.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@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
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} dynamic-args-call func dobj args
|
|
||||||
@deffnx {C Function} scm_dynamic_args_call (func, dobj, args)
|
|
||||||
Call the C function indicated by @var{func} and @var{dobj},
|
|
||||||
just like @code{dynamic-call}, but pass it some arguments and
|
|
||||||
return its return value. The C function is expected to take
|
|
||||||
two arguments and return an @code{int}, just like @code{main}:
|
|
||||||
@smallexample
|
|
||||||
int c_func (int argc, char **argv);
|
|
||||||
@end smallexample
|
|
||||||
|
|
||||||
The parameter @var{args} must be a list of strings and is
|
|
||||||
converted into an array of @code{char *}. The array is passed
|
|
||||||
in @var{argv} and its size in @var{argc}. The return value is
|
|
||||||
converted to a Scheme number and returned from the call to
|
|
||||||
@code{dynamic-args-call}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
When dynamic linking is disabled or not supported on your system,
|
|
||||||
the above functions throw errors, but they are still available.
|
|
||||||
|
|
||||||
Here is a small example that works on GNU/Linux:
|
|
||||||
|
|
||||||
@smallexample
|
|
||||||
(define libc-obj (dynamic-link "libc.so"))
|
|
||||||
libc-obj
|
|
||||||
@result{} #<dynamic-object "libc.so">
|
|
||||||
(dynamic-args-call 'rand libc-obj '())
|
|
||||||
@result{} 269167349
|
|
||||||
(dynamic-unlink libc-obj)
|
|
||||||
libc-obj
|
|
||||||
@result{} #<dynamic-object "libc.so" (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.
|
|
||||||
|
|
||||||
The functions to call a function from a dynamically linked library,
|
|
||||||
@code{dynamic-call} and @code{dynamic-args-call}, are not very powerful.
|
|
||||||
They are 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} and
|
|
||||||
@code{dynamic-args-call}. Instead, the usual way would be to write a
|
|
||||||
special Guile<->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.
|
|
||||||
|
|
||||||
From this setup 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.
|
|
||||||
|
|
||||||
There is, however, another possibility to get a more thorough access to
|
|
||||||
the functions contained in a dynamically linked library. Anthony Green
|
|
||||||
has written @file{libffi}, a library that implements a @dfn{foreign
|
|
||||||
function interface} for a number of different platforms. With it, you
|
|
||||||
can extend the Spartan functionality of @code{dynamic-call} and
|
|
||||||
@code{dynamic-args-call} considerably. There is glue code available in
|
|
||||||
the Guile contrib archive to make @file{libffi} accessible from Guile.
|
|
||||||
|
|
||||||
@node Compiled Code Modules
|
|
||||||
@subsubsection Putting Compiled Code into Modules
|
|
||||||
|
|
||||||
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 @code{(guile-user)} module
|
|
||||||
by default. However, it is also possible to put new primitives into
|
|
||||||
other modules.
|
|
||||||
|
|
||||||
The mechanism for doing so is not very well thought out and is likely to
|
|
||||||
change when the module system of Guile itself is revised, but it is
|
|
||||||
simple and useful enough to document it as it stands.
|
|
||||||
|
|
||||||
What @code{scm_c_define_gsubr} and the functions used by the snarfer
|
|
||||||
really do is to add the new primitives to whatever module is the
|
|
||||||
@emph{current module} when they are called. This is analogous to the
|
|
||||||
way Scheme code is put into modules: the @code{define-module} expression
|
|
||||||
at the top of a Scheme source file creates a new module and makes it the
|
|
||||||
current module while the rest of the file is evaluated. The
|
|
||||||
@code{define} expressions in that file then add their new definitions to
|
|
||||||
this current module.
|
|
||||||
|
|
||||||
Therefore, all we need to do is to make sure that the right module is
|
|
||||||
current when calling @code{scm_c_define_gsubr} for our new primitives.
|
|
||||||
|
|
||||||
@node Dynamic Linking and Compiled Code Modules
|
|
||||||
@subsubsection Dynamic Linking and Compiled Code Modules
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
@c FIXME::martin: Change all gh_ references to their scm_ equivalents.
|
|
||||||
|
|
||||||
@smallexample
|
|
||||||
#include <math.h>
|
|
||||||
#include <libguile.h>
|
|
||||||
|
|
||||||
SCM
|
|
||||||
j0_wrapper (SCM x)
|
|
||||||
@{
|
|
||||||
return scm_double2num (j0 (scm_num2dbl (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!
|
|
||||||
|
|
||||||
@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.
|
|
||||||
|
|
||||||
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,
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(define-module (bla blum))
|
|
||||||
|
|
||||||
(load-extension "libguile-bla-blum" "bla_init_blum")
|
|
||||||
@end lisp
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node Compiled Code Installation
|
|
||||||
@subsubsection Compiled Code Installation
|
|
||||||
|
|
||||||
The simplest way to write a module using compiled C code is
|
|
||||||
|
|
||||||
@example
|
|
||||||
(define-module (foo bar))
|
|
||||||
(load-extension "foobar-c-code" "foo_bar_init")
|
|
||||||
@end example
|
|
||||||
|
|
||||||
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 the standard system locations, such as @file{/usr/lib}
|
|
||||||
or @file{/usr/local/lib}.
|
|
||||||
|
|
||||||
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 "XXlibdirXX/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|XXlibdirXX|$(libdir)|' <foo.scm.in >foo.scm
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The actual pattern @code{XXlibdirXX} 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{libdir} location, and use that as required.
|
|
||||||
|
|
||||||
@example
|
|
||||||
(define-module (foo config))
|
|
||||||
(define-public foo-config-libdir "XXlibdirXX"")
|
|
||||||
@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}).
|
|
||||||
|
|
||||||
When installing multiple C code objects, it can be convenient to put
|
|
||||||
them in a subdirectory of @code{libdir}, thus giving for example
|
|
||||||
@code{/usr/lib/foo/some-obj.so}. If the objects are only meant to be
|
|
||||||
used through the module, then a subdirectory keeps them out of sight.
|
|
||||||
|
|
||||||
It will be noted all of the above requires that the Scheme code to be
|
|
||||||
found in @code{%load-path} (@pxref{Build Config}). 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.
|
|
||||||
|
|
||||||
Presently there's no convention for having a Guile version number in
|
|
||||||
module C code filenames or directories. This is primarily because
|
|
||||||
there's no established principles for two versions of Guile to be
|
|
||||||
installed under the same prefix (eg. two both under @file{/usr}).
|
|
||||||
Assuming upward compatibility is maintained then this should be
|
|
||||||
unnecessary, and if compatibility is not maintained then it's highly
|
|
||||||
likely a package will need to be revisited anyway.
|
|
||||||
|
|
||||||
The present suggestion is that modules should assume when they're
|
|
||||||
installed under a particular @code{prefix} that there's a single
|
|
||||||
version of Guile there, and the @code{guile-config} at build time has
|
|
||||||
the necessary information about it. C code or Scheme code might adapt
|
|
||||||
itself accordingly (allowing for features not available in an older
|
|
||||||
version for instance).
|
|
||||||
|
|
||||||
|
|
||||||
@node Variables
|
@node Variables
|
||||||
@subsection Variables
|
@subsection Variables
|
||||||
@tpindex Variables
|
@tpindex Variables
|
||||||
|
@ -1473,9 +918,6 @@ name @var{name} in the current module. But they can also be created
|
||||||
dynamically by calling one of the constructor procedures
|
dynamically by calling one of the constructor procedures
|
||||||
@code{make-variable} and @code{make-undefined-variable}.
|
@code{make-variable} and @code{make-undefined-variable}.
|
||||||
|
|
||||||
First-class variables are especially useful for interacting with the
|
|
||||||
current module system (@pxref{The Guile module system}).
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} make-undefined-variable
|
@deffn {Scheme Procedure} make-undefined-variable
|
||||||
@deffnx {C Function} scm_make_undefined_variable ()
|
@deffnx {C Function} scm_make_undefined_variable ()
|
||||||
Return a variable that is initially unbound.
|
Return a variable that is initially unbound.
|
||||||
|
@ -1513,6 +955,83 @@ return @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node provide and require
|
||||||
|
@subsection provide and require
|
||||||
|
|
||||||
|
Aubrey Jaffer, mostly to support his portable Scheme library SLIB,
|
||||||
|
implemented a provide/require mechanism for many Scheme implementations.
|
||||||
|
Library files in SLIB @emph{provide} a feature, and when user programs
|
||||||
|
@emph{require} that feature, the library file is loaded in.
|
||||||
|
|
||||||
|
For example, the file @file{random.scm} in the SLIB package contains the
|
||||||
|
line
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(provide 'random)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
so to use its procedures, a user would type
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(require 'random)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
and they would magically become available, @emph{but still have the same
|
||||||
|
names!} So this method is nice, but not as good as a full-featured
|
||||||
|
module system.
|
||||||
|
|
||||||
|
When SLIB is used with Guile, provide and require can be used to access
|
||||||
|
its facilities.
|
||||||
|
|
||||||
|
@node Environments
|
||||||
|
@subsection Environments
|
||||||
|
@cindex environment
|
||||||
|
|
||||||
|
Scheme, as defined in R5RS, does @emph{not} have a full module system.
|
||||||
|
However it does define the concept of a top-level @dfn{environment}.
|
||||||
|
Such an environment maps identifiers (symbols) to Scheme objects such
|
||||||
|
as procedures and lists: @ref{About Closure}. In other words, it
|
||||||
|
implements a set of @dfn{bindings}.
|
||||||
|
|
||||||
|
Environments in R5RS can be passed as the second argument to
|
||||||
|
@code{eval} (@pxref{Fly Evaluation}). Three procedures are defined to
|
||||||
|
return environments: @code{scheme-report-environment},
|
||||||
|
@code{null-environment} and @code{interaction-environment} (@pxref{Fly
|
||||||
|
Evaluation}).
|
||||||
|
|
||||||
|
In addition, in Guile any module can be used as an R5RS environment,
|
||||||
|
i.e., passed as the second argument to @code{eval}.
|
||||||
|
|
||||||
|
Note: the following two procedures are available only when the
|
||||||
|
@code{(ice-9 r5rs)} module is loaded:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(use-modules (ice-9 r5rs))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} scheme-report-environment version
|
||||||
|
@deffnx {Scheme Procedure} null-environment version
|
||||||
|
@var{version} must be the exact integer `5', corresponding to revision
|
||||||
|
5 of the Scheme report (the Revised^5 Report on Scheme).
|
||||||
|
@code{scheme-report-environment} returns a specifier for an
|
||||||
|
environment that is empty except for all bindings defined in the
|
||||||
|
report that are either required or both optional and supported by the
|
||||||
|
implementation. @code{null-environment} returns a specifier for an
|
||||||
|
environment that is empty except for the (syntactic) bindings for all
|
||||||
|
syntactic keywords defined in the report that are either required or
|
||||||
|
both optional and supported by the implementation.
|
||||||
|
|
||||||
|
Currently Guile does not support values of @var{version} for other
|
||||||
|
revisions of the report.
|
||||||
|
|
||||||
|
The effect of assigning (through the use of @code{eval}) a variable
|
||||||
|
bound in a @code{scheme-report-environment} (for example @code{car})
|
||||||
|
is unspecified. Currently the environments specified by
|
||||||
|
@code{scheme-report-environment} are not immutable in Guile.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@c Local Variables:
|
@c Local Variables:
|
||||||
@c TeX-master: "guile.texi"
|
@c TeX-master: "guile.texi"
|
||||||
@c End:
|
@c End:
|
||||||
|
|
|
@ -306,6 +306,7 @@ available through both Scheme and C interfaces.
|
||||||
* Memory Management:: Memory management and garbage collection.
|
* Memory Management:: Memory management and garbage collection.
|
||||||
* Objects:: Low level object orientation support.
|
* Objects:: Low level object orientation support.
|
||||||
* Modules:: Designing reusable code libraries.
|
* Modules:: Designing reusable code libraries.
|
||||||
|
* Foreign Function Interface:: Interacting with C procedures and data.
|
||||||
* Scheduling:: Threads, mutexes, asyncs and dynamic roots.
|
* Scheduling:: Threads, mutexes, asyncs and dynamic roots.
|
||||||
* Options and Config:: Configuration, features and runtime options.
|
* Options and Config:: Configuration, features and runtime options.
|
||||||
* Translation:: Support for translating other languages.
|
* Translation:: Support for translating other languages.
|
||||||
|
@ -330,6 +331,7 @@ available through both Scheme and C interfaces.
|
||||||
@include api-evaluation.texi
|
@include api-evaluation.texi
|
||||||
@include api-memory.texi
|
@include api-memory.texi
|
||||||
@include api-modules.texi
|
@include api-modules.texi
|
||||||
|
@include api-foreign.texi
|
||||||
@include api-scheduling.texi
|
@include api-scheduling.texi
|
||||||
@c object orientation support here
|
@c object orientation support here
|
||||||
@include api-options.texi
|
@include api-options.texi
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue