Dynamic Libraries in Tcl

Purpose: collect information, pointers, etc. regarding issues relating to Tcl and dynamic libraries.

Dynamic libraries - in Windows known as DLLs and in Unix often called shared libraries - are bodies of C code compiled and linked in a manner that make it possible for the code to be read into memory and made a part of running processes.

In Tcl, if the appropriate C code is provided, and the code is compiled properly, one can make use of Tcl's load command to load a dynamic library into an interpreter creating one or more new tcl commands.

Configuring Source code issues

When configuing tcl, one seems to need to make certain that one specifies --enable-shared and not specify --disable-load .

Anyone know why the flags are two different words? Is shared and load really two different conditions?

DGP Yes, those configuration options specify two different things. --enable-shared (default) vs. --disable-shared determines whether or not the Tcl library you build is a shared library or a static library. --enable-load (default) vs. --disable-load determines whether or not the Tcl library you build supports a working load command.

LV When you say "[...] supports a working load command", do you mean that --disable-load results in a Tcl library which does not recognize load as a valid command?

DGP No. When a --disable-load configuration of the Tcl library is built, it contains a load command that is the functional equivalent of the command [error "dynamic loading is not currently available on this system"]

LV However, the --enable-shared/--disable-shared , at least if present, would indicate that the extension (or, in the case of Tcl itself, the base Tcl library) that is generated will be able to be loaded. Right?

MSW Nope. You can load an extension into a static interpreter, but only if load is functionally available. Whether or not your tcl library is static or dynamic itself doesn't matter.

LV Now I am confused. Are you saying that it doesn't matter how an extension is built, as long as one has a functional load command?

MSW Nope, I'm saying that you can load any dynamic library as long as a functional load command is there, no matter whether tcl itself is a dynamic lib or linked statically (which --enable/--disable-shared governs). It doesn't matter how tcl itself is built as long as you can load others stuff dynamically...

TV The mechanism of loading a library into a running process is different from the idea of linking a library (statically) with a program. You could make a big tcl/tk combination wish like I recently did for a on-top-of-windows-XP XFRee86 X-server based Tk , where all functions are linked in and available in one executable program file.

Alternatively you can, as it is in certain distribution, have a very small basic wish.exe, which 'dynamically', that is when it is running, loads a tcl and after that, other code, such as the Tk library.

The problem with these dynamically linked libraries is that the program isn't a unit at startup which has been completely built at compile time; as can be imagined you could easily load the wrong version of a Tk library, which may work all wrong. Another problem often seen is that of dependencies. For instance, the TkImg library, if configured with all currently supported file formats, has dependencies on libtiff, libjpg, libpng, etc. If all of these are built dynamically, then one has to ensure that all can be found when attempting to load TkImg.

Internally, a dynamic library contains a list of functions, and probably a table with the relative entry points of the functions in it, probably with names, though I'm sure that varies per OS. Sharing can refer to the fact that the library is used by more than one program, in computer/OS architecture sense a library could also be loaded in memory (or even functions in principle) once, and be used by more than one program, and even by more than one user. They would have to have reentrant functions for that, so that the memory would contain only one version of the library, which could also be loaded dynamically (when needed), which is used by more than one process (each with their own stackframe but running functions in the same, shared, addressspace), saving memory (and cache occupation). Stdio can be that way.

The Tcl load command enables an operating system's dynamic library facility to be used, and on top of the normal way to link such dynamic libraries and making the loading program access it functions, tcl demands that the functions to be loaded contain I think at least 1 tcl-hook function with given arguments and return value, so that the loaded library can be accessed in tcl, and its contents known, like the implemented tcl commands.

It makes little sense to load any library in tcl unless you want to access it in some binary way, which isn't trivial with any library; you'd have a list of functions, know their arguments, and the linker (normally a static) would resolve addressing. In tcl, you'd not know what functions are in, what their arguments are or mean, and have no way of calling functions at binary level (though pointers for instance).

Disabling shared library access in general, as I did when building the windows/X verison, makes sense when the compiler you use has no support for dynamic libraries, which then holds for both tcl itself and the load command, or when for other reasons that option is not desired, as in my case that I 'simply' make-ed the unix version on cygwin under windows, which is fine when using XFree86, but unix shared libraries wouldn't work because the windows dll mechanism is different from for instance .so shared libraries under various unix versions.

Stubs issues

See Stubs, Extension Stubs Tables, and Writing extensions for stubs and pre-stubs Tcl.

[Are there any wiki or non-wiki web references which could be inserted here that discuss the approrpriate calls one must make in a library for this?]

[What other wiki and non-wiki references would be useful here?]

What about Direct Shared Library Use for Tcl9?

Loading external libraries