|
Topics
Introduction
Compile Options
Initialization and Registering Commands
Accessing Variables
Introduction
Programming for X can be cumbersome, in comparison tcl/tk provides a quickand easy way of getting a graphical application up and running. Tcl/tk isa scripting language, and as such there are some things you just can't do, orcan't do easily. The answer is to use a hybrid of C and tcl/tk. The tcl/tksystem comes with libraries which allow a C program to call the tcl/tk interpreter and run tcl/tk scripts.
The provided library includes methods for initializing the environment,calling different scripts, and accessing variables. Using this hybrid environment also benefits the programmer by giving them access to featureswhich are inherent in X. Simple call back and timer functions allow theprogrammer to schedule events, and the ability to register a C function asa procedure in tcl/tk creates a powerful tool.
This document covers the basics of integrating tcl/tk scripts with C.
The Compile Options section describes the various librariesand include files necessary to create a program.
The Initialization and Registering Commands section explainshow to get started, and how to call a C function from a tcl/tk script. The last section Accessing Variables explains how to read andwrite tcl/tk variables from functions in C.
Compile Options
In order to access the tcl/tk library routines several things have to bedone to your source code and how you compile it. There are two include fileswhich have the declarations for the calls to the library:
- #include <tcl.h>
- #include <tk.h>
复制代码
Compiling for a hybrid application requires pointing the compiler at the rightinclude directories, the right libraries, and setting the right link flags.On top of settings for tcl/tk it is also necessary to include filesand libraries for X.
The following flags are those to be set when using g++, your own system may vary dependingon compiler and file locations.
- -I/software/tcl-7.4/include
- -I/software/tk-4.0/include
- -I/software/x11r5_dev/Include
- -L/software/tcl-7.4/lib
- -L/software/tk-4.0/lib
- -L/software/x11r5_dev/lib
- -ltk
- -ltcl
- -lX11
复制代码
Initialization and Registering Commands
Creating a hybrid tcl/tk & C application centres around a few choicecommands. The first of these is the "Tk_Main" function, which is used tohand over control of the program to the tcl/tk interpreter. This command doesnot return, so it should be the last line in your "main" function, once allof your program's initialization is done.
The "Tk_Main" function takes three parameters. The second parameter is anarray of strings, each string having a special meaning. The first parameter isthe number of indices in this array of strings. The third parameter is a pointer to a function which is called for initialization. This initializationfunction is where most of the work gets done.
The array of strings which is passed to "Tk_Main" informs the tcl/tkinterpreter of the name of the application and the location of the script whichhas the tcl/tk commands in it. This array is actually the command lineparameters which are passed to the wish-like interpreter. The first itemin the array gives the name of the application, and the second is the locationof the script to be run. If the script is not in the same directory as theexecutable, it is wise to use a fully qualified path.
Due to legacy reasons, tcl/tk requires that the strings passed into mostof its functions be modifiable, it also has the occasional problem with function scope. The easiest way to avoid these problems is to dynamicallyallocate the strings being passed in.
The following code fragment shows acall to "Tk_Main" using the application "Hello World" and the script"hello.tcl".
- // prototype for the initialization function
- int InitProc( Tcl_Interp *interp );
- // declare an array for two strings
- char *ppszArg[2];
- // allocate strings and set their contents
- ppszArg[0] = (char *)malloc( sizeof( char ) * 12 );
- ppszArg[1] = (char *)malloc( sizeof( char ) * 12 );
- strcpy( ppszArg[0], "Hello World" );
- strcpy( ppszArg[1], "./hello.tcl" );
- // the following call does not return
- Tk_Main( 2, ppszArg, InitProc );
复制代码
Initialization Functions
The call to "Tk_Main" hands over control of your program to the tcl/tk interpreter, but after some base initialization is done and before the tcl/tkscript is run a user defined function can be executed.
The above example showsa function of this type: "InitProc". This user defined initialization functionmust return an integer and takes one parameter Tcl_Interp *, a pointer to an interpreter.
Inside of the initialization function is where you create an actual interpreter with a call to "Tk_Init". The "Tk_Init" function takes one parameter and that is a pointer to an interpreter, this should just be the pointer passed into your initialization function. The following code is a barebones initialization function, more will be added later.
- int InitProc( Tcl_Interp *interp )
- {
- int iRet;
- // Initialize tk first
- iRet = Tk_Init( interp );
- if( iRet != TCL_OK)
- {
- fprintf( stderr, "Unable to Initialize TK!\n" );
- return( iRet );
- } // end if
- return( TCL_OK );
- } // end InitProc
复制代码
C Functions as tcl/tk procedures
By now you are familiar with procedure calls inside of tcl/tk script. It ispossible when programming a hybrid application to have a tcl/tk procedure calla C function. To accomplish this requires a call to the "Tcl_CreateCommand"function. This is normally done inside of the initialization function. Calling the function as a procedure in tcl/tk is just like calling any otherprocedure. No declaration for the procedure should exist in the tcl/tk script.
Functions which are to be registered as procedures have a very specific prototype. They must return an integer, and take four arguments. The first argument is of type "ClientData" which is a tcl/tk library type. The second argument is a pointer to the interpreter. The last two arguments are similarto the "argc" and "argv" arguments in a C "main" function. These two arguments are used to pass the parameters given to the tcl/tk procedure. The "argc"argument contains the number parameters passed to the tcl/tk procedure, andthe "argv" is an array of strings, each string containing a parameter.
- int Myfunc( ClientData Data, Tcl_Interp *pInterp, int argc, char *argv[] );
复制代码
When a function is registered to be used as a tcl/tk procedure it can have apointer associated with it, this pointer is passed in as the "ClientData". Theconcept of "ClientData" allows the programmer to associate a data structurewith a tcl/tk object, and calls to procedures can reference this object. Thisstructure is not often needed.As was mentioned earlier the registration process requires a call to the"Tcl_CreateCommand" function. This function takes five arguments. The first argument is a pointer to an interpreter. The second argument is a string whichis the name of the tcl/tk procedure. The third argument is a pointer to thefunction which is called when the tcl/tk procedure is invoked. The last two arguments are the "ClientData" item, and a pointer to a deletion routine. The deletion routine allows a C function to be called when the program exits in order to clean up structures associated with objects. Like "ClientData" the pointer to the deletion function is not often necessary. The following is a sample registration of the tcl/tk procedure called "hey_there" which is to call the above declared "Myfunc"
- Tcl_CreateCommand( interp, "hey_there", Myfunc, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );
复制代码
http://fringe.davesource.com/Fringe/Computers/Languages/tcl_tk/tcl_C.html
|
|