www.delorie.com/gnu/docs/smalltalk/gst_32.html   search  
Buy GNU books!

GNU Smalltalk User's Guide

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.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 2.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:

     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(11) 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 gst_interpreter_proxy 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(12). 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.st libblox

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.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003