sgitcl - Tcl shell for SGI
This man page describes the Tcl shell for SGI. This shell includes Tcl
and TclX, and a shared library command which allows a single executable
program to include any mix of extension libraries. The extension
libraries are built as shared objects. For example, the Tcl distribution
includes an extension library for tclMotif (or Tm), the Tcl binding to
the Motif widget toolkit.
For a summary of the Tcl language, see the Tcl(3) man page. For a
summary of the extensions added by TclX, see the TclX(3) man page. For
an overview of tclMotif, see the tclMotif(3) man page.
The remainder of this man page describes the dlopen command, used to open
and initialize extension libraries; and describes how to build an
existing extension package as a shared library.
Building a shared library [Toc] [Back]
Build the .so using the -shared option to ld or cc. Make sure that the
build line references all libraries that are needed by the extension
library; for example, Tk requires "-lX11 -lc -lm". Adding the
-no_unresolved flag will ensure that there are no unresolvable symbols
which will probably save you time later.
Many of the TCL packages come with a makefile that builds a .a archive
which can be given to ld to build the shared object. If not, you'll need
to identify what object files need to be included in the build; for
extensions that follow the conventions, this usually means everything
except the file containing the Tcl_AppInit routine, since your library
will be initialized by a TCL command.
If you are developing your own library, you will have to define an
initialization routine that adds your new Tcl commands to the interpreter
(using Tcl_CreateCommand) and performs any other necessary
initialization. By convention this routine is named "<module_name>_Init"
where <module_name> is a short acronym for your extension library (e.g.
Tk_Init, Tm_Init, TclX_Init). This routine takes a Tcl_Interp pointer as
its only argument. Build the shared object as described above.
Install the .so in /usr/lib or /usr/sgitcl/lib. Now you are ready to try
opening the library.
Opening a shared library
The dlopen command opens a dynamic shared object (using the dlopen system
call). An init or call (see below) may optionally be appended to the end
of the command. The first argument must be the name of the library to
open. The library name is passed directly to dlopen, which looks for it
in /usr/lib and /usr/sgitcl/lib (this was added to the sgitcl executable
at link time). If your LD_LIBRARY_PATH environment symbol is set, that
will also be searched. An absolute pathname may also be specified; see
the dlopen(3) man page for more information on the library path name.
The mode parameter is hard-coded to RLTD_LAZY.
After the library is opened successfully, a new TCL command will be added
with the same name as the library file; this command can be used to call
subroutines in the library by name, using the dlsym(3) system call to
resolve the symbol name. Two function prototypes are provided: the init
prototype and the call prototype. The prototypes are defined below:
void init_routine(Tcl_Interp* interp);
int call_routine(void *data, Tcl_Interp* interp,
int argc, char* argv);
The init prototype is specifically designed to call the initialization
routine for an extension package that would normally be called from the
Tcl_AppInit routine. For example, the following line will open and
initialize the tclMotif library (assuming it has been linked as a dynamic
dlopen libtclMotif.so init Tm_Init
This line will open the library libtclMotif.so, and then call the routine
Tm_Init, passing the Tcl_Interp pointer as its only argument.
The call prototype allows an arbitrary parameter list to be passed to the
routine, as an argc, argv vector, much like the interface to a Tcl
command. Any values specified after the routine name will be passed as
strings to the routine. For Example, the command:
dlopen mylib.so call myroutine one two three
Will open the library "mylib.so" and then call the routine named
"myroutine", passing a NULL for "data", the Tcl_Interp argument, the
value 3 for the argc parameter, and three strings: "one", "two", and
"three" in the argv array. A call_routine should return TCL_OK if
successful, or TCL_ERROR (with an appropriate error message deposited in
interp->result) on failure.
The return value of the dlopen command will be the value of interp>result,
which can be set by the init or call routine to a meaningful
value; the default return value is an empty string. Suppose we build a
library called libmine.so which has an init routine:
int My_Init(Tcl_Interp* interp)
and another routine:
int My_Command(ClientData data, Tcl_Interp* interp,
int argc, char* argv)
/* some interesting code */
strcpy(interp->result, "Finished My_Command");
(if you are programming in C++, be sure to specify these as 'extern "C"'
routines to avoid name mangling).
We have built the library libmine.so and put it in /usr/lib. Now we
sgitcl>dlopen libmine.so init My_Init
The init routine ran and sgitcl printed the returned value "My_Init"
Now we type:
sgitcl> dlopen libmine.so
sgitcl> libmine.so init My_Init
protcl> libmine.so call My_Command "this is a test" second $var
The call to My_Command will be passed:
argc set to 3 (three)
argv set to "this is a test"
argv set to "second"
argv set to the value of the TCL variable "var"
argv will be NULL (zero).
If the dlopen command returns an error:
First make sure you put the .so in /usr/lib or /usr/sgitcl/lib. If so,
then you probably have unresolvable symbols in your library; the best way
to avoid this is to specify -no_unresolved when you link the shared
object. Re-link the shared object and make sure there are no unresolved
symbols. If this doesn't work, refer to the documentation on the dlopen
If dlopen returns "no such routine <init-routine>":
The init routine you specified is not defined in the library. Make sure
the routine was included in the object list. Some packages may fold this
routine into the same file with Tcl_AppInit; in this case you will need
to edit this file to remove Tcl_AppInit (comment it out or use #ifdef's),
add the file to the link list and re-build the library.
Before any evaluation occures a system wide startup file named
system.<interp-name>rc is executed. A good way to automatically load in
a library of routines for a class of scripts is to create a link to
sgitcl with a new name and to create a system.namerc script in the Tcl
library directory, which will dlopen the appropriate library and do any
specific startup needed.
expect is a symbolic link to /usr/sgitcl/bin/sgitcl
dlopen libexpect.so init Exp_Init
eval exp_run [split $argv]
On interactive runs a per-user startup script ~/.<interp-name>rc is also
sourced just before dropping into the commandloop. This script can be
used by individuals to setup commonly used proceedures or to override
/usr/sgitcl/lib/system.sgitcl system wide startup script
$HOME/.sgitcl user startup script
PPPPaaaaggggeeee 4444 [ Back ]