Creating a Loadable Package

   

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 44.  C Programming and Tcl


You can organize your C code into a loadable package that can be dynamically linked into tclsh, wish, or your own Tcl application. The details about compiling the code into the shared library that contains the package are presented in Chapter 45. This section describes a package that implements the random Tcl command that returns random numbers.

The load Command

The Tcl load command is used to dynamically link in a compiled package:

 load library package ?interp? 

The library is the file name of the shared library file (i.e., the DLL), and package is the name of the package implemented by the library. This name corresponds to the package_Init procedure called to initialize the package (e.g., Random_Init) The optional interp argument lets you load the library into a slave interpreter. If the library is in /usr/local/lib/random.so, then a Tcl script can load the package like this:

 load /usr/local/lib/random.so Random 

On most UNIX systems, you can set the LD_LIBRARY_PATH environment variable to a colon-separated list of directories that contain shared libraries. If you do that, then you can use relative names for the libraries:

 load librandom.so Random 

On Macintosh, the load command looks for libraries in the same folder as the Tcl/Tk application (i.e., Wish) and in the System:Extensions:Tool Command Language folder:

 load random.shlib Random 

On Windows, load looks in the same directory as the Tcl/Tk application, the current directory, the C:\Windows\System directory (or C:\Windows\System32 on Windows NT), the C:\Windows directory, and then the directories listed in the PATH environment variable.

 load random.dll Random 

Fortunately, you usually do not have to worry about these details because the Tcl package facility can manage your libraries for you. Instead of invoking load directly, your scripts can use package require instead. The package facility keeps track of where your libraries are and knows how to call load for your platform. It is described in Chapter 12.

The Package Initialization Procedure

When a package is loaded, Tcl calls a C procedure named package_Init, where package is the name of your package. Example 44-1 defines Random_Init. It registers a command procedure, RandomCmd, that implements a new Tcl command, random. When the Tcl script uses the random command, the RandomCmd procedure will be invoked by the Tcl interpreter. Two styles of command registrations are made for comparison: the original Tcl_CreateCommand and the Tcl_CreateObjCommand added in Tcl 8.0. The command procedures are described in the next section:

Example 44-1 The initialization procedure for a loadable package.
 /*  * random.c  */ #include <tcl.h> /*  * Declarations for application-specific command procedures  */ int RandomCmd(ClientData clientData,              Tcl_Interp *interp,              int argc, char *argv[]); int RandomObjCmd(ClientData clientData,              Tcl_Interp *interp,              int objc, Tcl_Obj *CONST objv[]); /*  * Random_Init is called when the package is loaded.  */ int Random_Init(Tcl_Interp *interp) {    /*     * Initialize the stub table interface, which is     * described in Chapter 45.     */    if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {       return TCL_ERROR;    }    /*     * Register two variations of random.     * The orandom command uses the object interface.     */    Tcl_CreateCommand(interp, "random", RandomCmd,           (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);    Tcl_CreateObjCommand(interp, "orandom", RandomObjCmd,           (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);    /*     * Declare that we implement the random package     * so scripts that do "package require random"     * can load the library automatically.     */    Tcl_PkgProvide(interp, "random", "1.1");    return TCL_OK; } 

Using Tcl_PkgProvide

Random_Init uses Tcl_PkgProvide to declare what package is provided by the C code. This call helps the pkg_mkIndex procedure learn what libraries provide which packages. pkg_mkIndex saves this information in a package database, which is a file named pkgIndex.tcl. The package require command looks for the package database files along your auto_path and automatically loads your package. The general process is:

  • Create your shared library and put it into a directory listed on your auto_path variable, or a subdirectory of one of the directories on your auto_path.

  • Run the pkg_mkIndex procedure in that directory, giving it the names of all the script files and shared libraries it should index. Now your shared library is ready for use by other scripts.

  • A script uses package require to request a package. The correct load command for your system will be used the first time a command from your package is used. The package command is the same on all platforms:

     package require random => 1.1 

    This process is explained in more detail on page 165.


       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net