Version 9 of load

Updated 2008-10-29 14:54:45 by LV

Dynamically links a code library (typically written in C, C++, or some comparable language) with the program containing the Tcl interpreter. Most extensions use this mechanism.

http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/load.htm


  • What does one need to create an extension to be loaded?
  • What does one need to load Tk?

See also:


Clif Flynt has made available a useful C extension to load shared libraries that don't know anything about tcl's _Init function.

The extension allows one to invoke dlopen to load libraries that do not have Tcl entry points (for use by other things that do have legitimate foo_Init entry points).

The dlopen extension is available at:

http://noucorp.com/cgi-bin/noucorp/generic.tcl?dir=/home/httpd/html/tcl/utilities

It's a minimal, single C file extension, but it has been known to work on both Windows and Posix (just retested on Linux)


Basics of DLL Creation for Tcl extension.

You have a design for some software that will be implemented in a dll written in C (or C++ code with extern "C" {} around it). You must write the active code in a function, and add some initialisation code to register the dll's functions with tcl (Tcl_CreateCommand or Tcl_CreateObjCommand is faster).

The initialisation required in the code that compiles to make tclext.dll (the tclext_Init name is composed from the dll name by Tcl):

  // this is your useful procedure. It can be a C++ or C linked procedure.
 int tclextfunction (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
     // dosomething - clientdata is a pointer to something the programmer may or may not define
     return TCL_OK;
 }
 #ifdef __cplusplus
 extern "C" {
 #endif
 int PROBE_EXPORT tclext_Init(Tcl_Interp *interp)
 {
 //        tcl stubs and tk stubs are needed for dynamic loading, you must have this set as a compiler option
 #ifdef USE_TCL_STUBS
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
                        Tcl_SetResult(interp, "Tcl_InitStubs failed",TCL_STATIC);
                return TCL_ERROR;
    }
 #endif
 #ifdef USE_TK_STUBS
    if (Tk_InitStubs(interp, TCL_VERSION, 1) == NULL) {
                        Tcl_SetResult(interp, "Tk_InitStubs failed",TCL_STATIC);
                return TCL_ERROR;
    }
 #endif
    Tcl_CreateCommand( "tclextfunction", tclextfunction ); // register your functions with Tcl
 }
 #ifdef __cplusplus
 }
 #endif

Then in Tcl script use

  load tclext.dll
  tclextfunction  a b c

to pass the strings a,b,c to tclextfunction in the array argv - argc will be 3 of course. The ClientData is a pointer to anything (perhaps a global data structure or a class defined by a Tcl_ClientData statement often dynamically allocated in the tclext_Init function).

The reader should be able to find all the required .h files from the net without any more help from me.


So what do you do when load, or, even more mysteriously, package, fails? There are many, many ways for this to happen, and typical built-in diagnostics from supplied loaders are inscrutable.

One handy tool for such situations is a dependency utility. Under Windows, DependencyWalker [L1 ] walks dependencies. When you let it load a specific dll, it assists you in determining what other DLLs it needs.


See also: