Back: C and Smalltalk
Up: C and Smalltalk
Forward: C callout
 
Top: GNU Smalltalk User's Guide
Contents: Table of Contents
Index: Class index
About: About this document

4.1 Linking your libraries to the virtual machine

A nice thing you can do with GNU Smalltalk is enhancing it with your own goodies. If they're written in Smalltalk only, no problem: getting them to work as packages (see section 3.7 Packages), and to fit in with the GNU Smalltalk packaging system, is likely to be a five-minutes task.

If your goodie is mostly written in C and you don't need particular glue to link it to Smalltalk (for example, there are no callbacks from C code to Smalltalk code), you can use the dynamic library linking system. When using this system, you have to link GNU Smalltalk with the library at run-time using DLD; the method to be used here is DLD class>>#addLibrary:.

But if you want to provide a more intimate link between C and Smalltalk, as is the case with Blox, you should use the dynamic module linking system. This section explains what to do, taking the Blox library as a guide.

Modules are searched for in the `gnu-smalltalk' subdirectory of the system library path, or in the directory that the SMALLTALK_MODULES environment variable points to. A module is distinguished from a standard shared library because it has a function which Smalltalk calls to initialize the module; the name of this function must be gst_initModule. Here is the initialization function used by Blox:

 
void
gst_initModule(proxy)
     VMProxy *proxy;
{
  vmProxy = proxy;
  vmProxy->defineCFunc("Tcl_Eval", Tcl_Eval);
  vmProxy->defineCFunc("Tcl_GetStringResult", Tcl_GetStringResult);
  vmProxy->defineCFunc("tclInit", tclInit);
  vmProxy->defineCFunc("bloxIdle", bloxIdle);
}

Note that the defineCFunc function is called through a function pointer in gst_initModule, and that Blox saves the value of its parameter to be used elsewhere in its code. This is not strictly necessary on many platforms, namely those where the module is effectively linked with the Smalltalk virtual machine at run-time; but since some(9) cannot obtain this, for maximum portability you must always call the virtual machine through the proxy and never refer to any symbol which the virtual machine exports. For uniformity, even programs that link with `libgst.a' should not call these functions directly, but through a VMProxy exported by `libgst.a' and accessible through the interpreterProxy variable.

First of all, you have to build your package as a shared library; using GNU Automake and libtool, this is as easy as changing your `Makefile.am' file so that it reads like this

 
pkglib_LTLIBRARIES = libblox.la
libblox_la_LDFLAGS = -module -no-undefined ... more flags ...
libblox_la_SOURCES = ... your source files ...

instead of reading like this

 
pkglib_LIBRARIES = libblox.a
libblox_a_LDFLAGS = ... more flags ...
libblox_a_SOURCES = ... your source files ...

As you see, you only have to change `.a' extensions to `.la', LIBRARIES targets to LTLIBRARIES, and add appropriate options to LDFLAGS(10). You will also have to run libtoolize and follow its instruction, but this is really simpler than it looks.

Note that this example uses `pkglib' because TCP is installed together with Smalltalk, but in general this is not necessary. You can install the library wherever you want; libtool will even generate appropriate warnings to the installer if ldconfig (or an equivalent program) has to be re-run.

Finally, you will have to specify the name of the module in the `packages' file. In this case, the relevant entry in that file will be

 
Blox
    Kernel
    Blox.st libblox
    ../blox

Everything not ending with `.st' will be picked by the package loader as a module, and will be passed to DLD class>>#addModule: before attempting to file-in the Smalltalk source files.




This document was generated on May, 12 2002 using texi2html