Tcl_Main and Tcl_AppInit

   

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

Table of Contents
Chapter 44.  C Programming and Tcl


Tcl_Main and Tcl_AppInit

This section describes how to make a custom main program that includes Tcl. However, the need for custom main programs has been reduced by the use of loadable modules. If you create your commands as a loadable package, you can just load them into tclsh or wish. Even if you do not need a custom main, this section will explain how all the pieces fit together.

The Tcl library supports the basic application structure through the Tcl_Main procedure that is designed to be called from your main program. Tcl_Main does three things:

  • It calls Tcl_CreateInterp to create an interpreter that includes all the standard Tcl commands like set and proc. It also defines a few Tcl variables like argc and argv. These have the command-line arguments that were passed to your application.

  • It calls Tcl_AppInit, which is not part of the Tcl library. Instead, your application provides this procedure. In Tcl_AppInit you can register additional application-specific Tcl commands.

  • It reads a script or goes into an interactive loop.

You call Tcl_Main from your main program and provide an implementation of the Tcl_AppInit procedure:

Example 44-13 A canonical Tcl main program and Tcl_AppInit.
 /* main.c */ #include <tcl.h> int Tcl_AppInit(Tcl_Interp *interp); /*  * Declarations for application-specific command procedures  */ int Plus1ObjCmd(ClientData clientData,              Tcl_Interp *interp,              int objc, Tcl_Obj *CONST objv[]); main(int argc, char *argv[]) {    /*     * Initialize your application here.     *     * Then initialize and run Tcl.     */    Tcl_Main(argc, argv, Tcl_AppInit);    exit(0); } /*  * Tcl_AppInit is called from Tcl_Main  * after the Tcl interpreter has been created,  * and before the script file  * or interactive command loop is entered.  */ int Tcl_AppInit(Tcl_Interp *interp) {    /*     * Tcl_Init reads init.tcl from the Tcl script library.     */    if (Tcl_Init(interp) == TCL_ERROR) {       return TCL_ERROR;    }    /*     * Register application-specific commands.     */    Tcl_CreateObjCommand(interp, "plus1", Plus1ObjCmd,           (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);    Random_Init(interp);    Blob_Init(interp);    /*     * Define the start-up filename. This file is read in     * case the program is run interactively.     */    Tcl_SetVar(interp, "tcl_rcFileName", "~/.mytcl",       TCL_GLOBAL_ONLY);    /*     * Test of Tcl_Invoke, which is defined on page 635.     */    Tcl_Invoke(interp, "set", "foo", "$xyz [foo] {", NULL);    return TCL_OK; } 

The main program calls Tcl_Main with the argc and argv parameters passed into the program. These are the strings passed to the program on the command line, and Tcl_Main will store these values into Tcl variables by the same name. Tcl_Main is also given the address of the initialization procedure, which is Tcl_AppInit in our example. Tcl_AppInit is called by Tcl_Main with one argument, a handle on a newly created interpreter. There are three parts to the Tcl_AppInit procedure:

  • The first part initializes the various packages the application uses. The example calls Tcl_Init to set up the script library facility described in Chapter 12. The core Tcl commands have already been defined by Tcl_CreateInterp, which is called by Tcl_Main before the call to Tcl_AppInit.

  • The second part of Tcl_AppInit does application-specific initialization. The example registers the command procedures defined earlier in this Chapter.

  • The third part defines a Tcl variable, tcl_RcFileName, which names an application startup script that executes if the program is used interactively.

You can use your custom program just like tclsh, except that it includes the additional commands you define in your Tcl_AppInit procedure. The sample makefile on the CD creates a program named mytcl. You can compile and run that program and test random and the other commands.

Tk_Main

The structure of Tk applications is similar. The Tk_Main procedure creates a Tcl interpreter and the main Tk window. It calls out to a procedure you provide to complete initialization. After your Tk_AppInit returns, Tk_Main goes into an event loop until all the windows in your application have been destroyed.

Example 44-14 shows a Tk_AppInit used with Tk_Main. The main program processes its own command-line arguments using Tk_ParseArgv, which requires a Tcl interpreter for error reporting. The Tk_AppInit procedure initializes the clock widget example that is the topic of Chapter 46:

Example 44-14 A canonical Tk main program and Tk_AppInit.
 /* main.c */ #include <tk.h> int Tk_AppInit(Tcl_Interp *interp); /*  * A table for command line arguments.  */ char *myoption1 = NULL; int myint2 = 0; static Tk_ArgvInfo argTable[] = {    {"-myoption1", TK_ARGV_STRING, (char *) NULL,       (char *) &myoption1, "Explain myoption1"},    {"-myint2", TK_ARGV_CONSTANT, (char *) 1, (char *) &myint2,       "Explain myint2"},    {"", TK_ARGV_END, }, }; main(int argc, char *argv[]) {    Tcl_Interp *interp;    /*     * Create an interpreter for the error message from     * Tk_ParseArgv. Another one is created by Tk_Main.     * Parse our arguments and leave the rest to Tk_Main.     */    interp = Tcl_CreateInterp();    if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv,          argTable, 0) != TCL_OK) {       fprintf(stderr, "%s\n", interp->result);       exit(1);    }    Tcl_DeleteInterp(interp);    Tk_Main(argc, argv, Tk_AppInit);    exit(0); } int ClockCmd(ClientData clientData,              Tcl_Interp *interp,              int argc, char *argv[]); int ClockObjCmd(ClientData clientData,              Tcl_Interp *interp,              int objc, Tcl_Obj *CONST objv[]); void ClockObjDestroy(ClientData clientData); int Tk_AppInit(Tcl_Interp *interp) {    /*     * Initialize packages     */    if (Tcl_Init(interp) == TCL_ERROR) {       return TCL_ERROR;    }    if (Tk_Init(interp) == TCL_ERROR) {       return TCL_ERROR;    }    /*     * Define application-specific commands here.     */    Tcl_CreateCommand(interp, "wclock", ClockCmd,       (ClientData)Tk_MainWindow(interp),       (Tcl_CmdDeleteProc *)NULL);    Tcl_CreateObjCommand(interp, "oclock", ClockObjCmd,       (ClientData)NULL, ClockObjDestroy);    /*     * Define start-up filename. This file is read in     * case the program is run interactively.     */    Tcl_SetVar(interp, "tcl_rcFileName", "~/.mytcl",       TCL_GLOBAL_ONLY);    return TCL_OK; } 

       
    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