756 |
@node Extensions |
@node Extensions |
757 |
@subsection Writing Dynamically Loadable Extensions |
@subsection Writing Dynamically Loadable Extensions |
758 |
|
|
759 |
XXX - document @code{load-extension}, @code{scm_register_extension} |
Higher level linking routines allow you to manage loadable modules when |
760 |
|
multiple scheme modules require the same dynamically linked library. As |
761 |
|
we described in section @xref{A Sample Guile Extension}, we write a C |
762 |
|
module which contains an init function, and then use the |
763 |
|
@code{load-extension} to link the library and run the init function. |
764 |
|
However, let's assume that we had two scheme modules (for example, (math |
765 |
|
general) and (science electrons)) which both required the |
766 |
|
@code{libguile-bessel} routines. We would not want to link the shared |
767 |
|
file twice because it wastes memory, and even if we were not concerned |
768 |
|
with that, it would create symbol conflicts. We cannot designate one to |
769 |
|
do the loading, since we may only want one or the other (or both) at any |
770 |
|
given time. These routines solve this problem. |
771 |
|
|
772 |
|
@deffn {Scheme Procedure} load-extension lib init |
773 |
|
@deffnx {C Function} scm_load_extension (SCM lib, SCM init) |
774 |
|
@deffnx {C Function} scm_c_load_extension (const char *lib, const char *init) |
775 |
|
@end deffn |
776 |
|
|
777 |
|
Most of the time, when this function is called, it is equivalent to |
778 |
|
calling @code{(dynamic-call init (dynamic-link lib))}. It simply uses |
779 |
|
the low-level dynamic linking routines to link the shared file, and call |
780 |
|
its init function. However, if the library and init function has been |
781 |
|
pre-registered, it skips the linking of the shared file, and calls the |
782 |
|
replacement init function which was designated by the registration. |
783 |
|
That way both of our modules can contain the line |
784 |
|
|
785 |
|
@smalllisp |
786 |
|
(load-extension "libguile-bessel" "init_bessel") |
787 |
|
@end smalllisp |
788 |
|
|
789 |
|
If, for example, (math general) gets loaded first, then it will do the |
790 |
|
standard thing and links the shared file, and calls init_bessel. When |
791 |
|
(science electrons) gets loaded, the load-extension line does not cause |
792 |
|
the shared file to be linked. Instead it simply causes the replacement |
793 |
|
init function to be run. |
794 |
|
|
795 |
|
@deffn {C Function} scm_c_register_extension (const char *lib, const char *init, void (*func) (void *), void *data) |
796 |
|
@end deffn |
797 |
|
|
798 |
|
We utilize @code{scm_c_register_extension} from the init function of our |
799 |
|
module to register our replacement function. The bessel function |
800 |
|
example would then look like |
801 |
|
|
802 |
|
@smallexample |
803 |
|
#include <math.h> |
804 |
|
#include <libguile.h> |
805 |
|
|
806 |
|
static double pi; /* Random Global Variable */ |
807 |
|
|
808 |
|
SCM |
809 |
|
j0_wrapper (SCM x) |
810 |
|
@{ |
811 |
|
return scm_make_real (j0 (scm_num2dbl (x, "j0"))); |
812 |
|
@} |
813 |
|
|
814 |
|
void |
815 |
|
define_functions (void *data) |
816 |
|
@{ |
817 |
|
scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper); |
818 |
|
@} |
819 |
|
|
820 |
|
void |
821 |
|
init_bessel () |
822 |
|
@{ |
823 |
|
pi = 3.14159265; /* Initialize our global var */ |
824 |
|
define_functions (NULL); |
825 |
|
scm_c_register_extension ("libguile-bessel", "init_bessel", |
826 |
|
define_functions, NULL); |
827 |
|
@} |
828 |
|
|
829 |
|
@end smallexample |
830 |
|
|
831 |
|
This way the first time @code{load-extension} is called, the shared |
832 |
|
library is linked, the global variable is initialized, the proper scheme |
833 |
|
functions (@code{j0}) are defined, and the replacement init function is |
834 |
|
registered. The second time @code{load-extension} is called, it finds |
835 |
|
the replacement function and calls @code{define_functions}, without |
836 |
|
redundantly attempting to link the shared file, or reinitializing our |
837 |
|
global variables. |
838 |
|
|
839 |
|
The fourth argument to @code{scm_c_register_extension} is a pointer |
840 |
|
which gets passed to the replacement init function which you can use |
841 |
|
for anything your init function might need. |
842 |
|
|
843 |
|
The first (@code{lib}) argument is allowed to be NULL. In which case |
844 |
|
only the @code{init} argument is used when searching through the |
845 |
|
registered extensions. This is useful when you don't know the library |
846 |
|
name (which isn't really relevant anyway in a completely linked |
847 |
|
program) and you are sure that INIT is unique (which it must be for |
848 |
|
static linking). |
849 |
|
|
850 |
|
|
851 |
@node Variables |
@node Variables |