Next: , Up: Dynamic Libraries


31.11.1 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.

— Scheme Procedure: dynamic-link name
— C Function: scm_dynamic_link (name)

Open the dynamic library file name and return its library handle, suitable for passing to the following functions. As a special case, if name is #f, the returned handle is for the Guile executable itself.

— Scheme Procedure: dynamic-object? obj
— C Function: scm_dynamic_object_p (obj)

Return #t iff obj is a dynamic library handle.

— Scheme Procedure: dynamic-unlink h
— C Function: scm_dynamic_unlink (h)

Unlink the library represented by dynamic library handle h and remove any imported symbols from the address space.

— Scheme Procedure: dynamic-func name h
— C Function: scm_dynamic_func (name, h)

Import the function name from h, a dynamic library handle, and return a dynamic function handle. At the moment, the dynamic function handle is formed by casting the address of name to C type long and converting this number to its Scheme representation.

Regardless whether your C compiler prepends an underscore ‘_’ to the global names in a program, you should not include this underscore in function. Guile knows whether the underscore is needed or not and will add it when necessary.

— Scheme Procedure: dynamic-call lib-thunk h
— C Function: scm_dynamic_call (lib-thunk, h)

Call lib-thunk, a procedure of no arguments. If lib-thunk is a string, it is assumed to be a symbol found in the dynamic library h and is fetched with dynamic-func. Otherwise, it should be a function handle returned by a previous call to dynamic-func.

Interrupts are deferred while the C function is executing (with SCM_DEFER_INTS and SCM_ALLOW_INTS).

— Scheme Procedure: dynamic-args-call proc h args
— C Function: scm_dynamic_args_call (proc, h, args)

Call proc, a dynamically loaded function, passing it args (a list of strings) in the standard (int argc, char **argv) manner. As with dynamic-call, proc should be either a function handle or a string, in which case it is first fetched from h with dynamic-func.

proc should return an integer, which is used as the return value from dynamic-args-call.

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:

     (define libc-obj (dynamic-link "libc.so"))
     libc-obj
     ⇒ #<dynamic-object "libc.so">
     (dynamic-args-call 'rand libc-obj '())
     ⇒ 269167349
     (dynamic-unlink libc-obj)
     libc-obj
     ⇒ #<dynamic-object "libc.so" (unlinked)>

As you can see, after calling dynamic-unlink on a dynamically linked library, it is marked as ‘(unlinked)’ and you are no longer able to use it with 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, 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, dynamic-call and 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 libX11 with dynamic-link and then construct a beautiful graphical user interface just by using dynamic-call and 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 libffi, a library that implements a foreign function interface for a number of different platforms. With it, you can extend the Spartan functionality of dynamic-call and dynamic-args-call considerably. There is glue code available in the Guile contrib archive to make libffi accessible from Guile.