guile-sources
[Top][All Lists]
Advanced

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

PATCH: scheme-modules.texi (2)


From: Aaron VanDevender
Subject: PATCH: scheme-modules.texi (2)
Date: Fri, 29 Aug 2003 09:27:25 -0400
User-agent: Mutt/1.2.5.1i

I found a couple of mistakes in my original scheme-modules.texi
patch, so here is a newer version.


cya
.sig


--- guile-core.old/doc/ref/scheme-modules.texi  2003-08-28 23:35:16.000000000 
-0500
+++ guile-core/doc/ref/scheme-modules.texi      2003-08-29 08:22:12.000000000 
-0500
@@ -756,8 +756,97 @@
 @node Extensions
 @subsection Writing Dynamically Loadable Extensions
 
-XXX - document @code{load-extension}, @code{scm_register_extension}
-
+Higher level linking routines allow you to manage loadable modules
+when multiple scheme modules require the same dynamically linked
+library. As we described in section @xref{A Sample Guile Extension},
+we write a C module which contains an init function, and then use the
address@hidden to link the library and run the init
+function. However, lets assume that we had two scheme modules (for
+example, (math general) and (science electrons)) which both required
+the @code{libguile-bessel} routines. We would not want to link the shared
+file twice because its wasts memory, and even if we were not concerned
+with that, it would create symbol conflicts which we cannot abide. We
+cannot designate one to do the loading since, we may only want one or
+the other (or both) at any given time. These routines solve this
+problem.
+
address@hidden {Scheme Procedure} load-extension lib init
address@hidden {C Function} scm_load_extension (SCM lib, SCM init)
address@hidden {C Function} scm_c_load_extension (const char *lib, const char 
*init)
address@hidden deffn
+
+Most of the time, when this function is called, it is equivalent to
+calling @code{(dynamic-call init (dynamic-link lib))}. It simply uses
+the low-level dynamic linking routines to link the shared file, and
+call its init function. However, if the library and init function has
+been pre-registered, it skips the linking of the shared file, and
+calls the replacement init function which was designated by the
+registration. That way both of our modules can contain the line
+
address@hidden
+(load-extension "libguile-bessel" "init_bessel")
address@hidden smalllisp
+
+If, for example, (math general) gets loaded first, then it will do the
+standard thing and links the shared file, and calls init_bessel. When
+(science electrons) gets loaded, the load-extension line does not
+cause the shared file to be linked. Instead it simply causes the
+replacement init function to be run.
+
address@hidden {C Function} scm_c_register_extension (const char *lib, const 
char *init, void (*func) (void *), void *data)
address@hidden deffn
+
+We utilize @code{scm_c_register_extension} from the init function of
+our module to register our replacement function. Our bessel function
+example would then look like
+
address@hidden
+#include <math.h>
+#include <libguile.h>
+
+static double pi; /* Random Global Variable */
+
+SCM
+j0_wrapper (SCM x)
address@hidden
+  return scm_make_real (j0 (scm_num2dbl (x, "j0")));
address@hidden
+
+void 
+define_functions (void *data)
address@hidden
+  scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
address@hidden
+
+void
+init_bessel ()
address@hidden
+  pi = 3.14159265; /* Initialize our global var */
+  define_functions (NULL);
+  scm_c_register_extension ("libguile-bessel", "init_bessel", 
+                            define_functions, NULL);
address@hidden
+
address@hidden smallexample
+
+This way the first time @code{load-extension} is called, the shared
+library is linked, the global variable is initialize, the proper
+scheme functions (@code{j0}) are defined, and the replacement init
+function is registered. The second time @code{load-extension} is
+called, it finds the replacement function and calls
address@hidden, with out redundantly attempting to link the
+shared file, or reinitializing our global variables.
+
+The fourth argument to @code{scm_c_register_extension} is a pointer
+which gets passed to the replacement init function which you can use
+for anything your init function might need.
+
+The first (@code{lib}) argument is allowed to be NULL. In which case
+only the @code{init} argument is used when searching through the
+registered extensions.  This is useful when you don't know the library
+name (which isn't really relevant anyway in a completely linked
+program) and you are sure that INIT is unique (which it must be for
+static linking).
 
 @node Variables
 @section Variables




reply via email to

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