This section explains how to make the Bessel functions of the C library
available to Scheme. 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 j0
function.
Consider the following file bessel.c.
#include <math.h> #include <libguile.h> SCM j0_wrapper (SCM x) { return scm_from_double (j0 (scm_to_double (x))); } void init_bessel () { scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper); }
This C source file needs to be compiled into a shared library. Here is how to do it on GNU/Linux:
gcc `pkg-config --cflags guile-3.0` \ -shared -o libguile-bessel.so -fPIC bessel.c
For creating shared libraries portably, we recommend the use of GNU Libtool (see Introduction in GNU Libtool).
A shared library can be loaded into a running Guile process with the
function load-extension
. In addition to the name of the
library to load, this function also expects the name of a function from
that library that will be called to initialize it. For our example,
we are going to call the function init_bessel
which will make
j0_wrapper
available to Scheme programs with the name
j0
. Note that we do not specify a filename extension such as
.so when invoking load-extension
. The right extension for
the host platform will be provided automatically.
(load-extension "libguile-bessel" "init_bessel") (j0 2) ⇒ 0.223890779141236
For this to work, load-extension
must be able to find
libguile-bessel, of course. It will look in the places that
are usual for your operating system, and it will additionally look
into the directories listed in the LTDL_LIBRARY_PATH
environment variable.
To see how these Guile extensions via shared libraries relate to the module system, See Putting Extensions into Modules.