Tcl解释器(Tcl Interpreter)的创建和管理

风行水上 @ 2014-10-22 18:12:52
标签:

    本文是文章《Tcl/Tk Insight: C/C++ 扩展》的一部分。

    Tcl解释器(Tcl Interpreter)的创建和管理

    #include <tcl.h>
    #include <stdio.h>
    
    int run_tcl(int argc, char *argv[]){
      printf("Tcl_FindExecutable ...\n");
      Tcl_FindExecutable(argv[0]);
      // will fatal if no above line. XXX: on windows, used to check stderr channel
    
      int ret = TCL_OK;
    
      // 创建一个解释器
      printf("interp create ...\n");
      Tcl_Interp *interp = Tcl_CreateInterp();
      if(interp==NULL){
        printf("interp create fail\n");
      } else {
        printf("interp create pass\n");
      }
    
      const char *tcl_library = argv[1]; // where contains the file init.tcl
      const char *value = Tcl_SetVar(interp, 
          "tcl_library", tcl_library,
          TCL_GLOBAL_ONLY);
      printf("tcl_library = %s\n", value);
    
      // 执行"init.tcl"进行初始化
      if ( Tcl_Init( interp ) != TCL_OK ) {
         // Error
         printf("interp init fail\n");
         return TCL_ERROR;
      } else {
         printf("interp int pass\n");
      }
     
      if(Tcl_InterpDeleted(interp) != 0){
         // 解释器 已经被删除了
         printf("interp has been deleted\n");
         return TCL_ERROR;
      }
    
      // 执行Tcl命令
      const char *script = "set t 3 ; puts $t";
      printf("Tcl_Eval = %s\n", script);
      if(TCL_OK != Tcl_Eval(interp,script )){
         printf("Tcl_Eval fail\n");
         return TCL_ERROR;
      }
    
      // 执行Tcl文件
      printf("Tcl_EvalFile = %s\n", argv[2]);
      if(TCL_OK != Tcl_EvalFile(interp, argv[2])){
         printf("Tcl_EvalFile fail\n");
         return TCL_ERROR;
      }
    
      // 删除这个解释器
      Tcl_DeleteInterp(interp);
    
      return ret;
    }
    
    int main(int argc, char *argv[]){
      int ret = run_tcl(argc, argv);
      printf("exit code = %d\n", ret);
    
      return ret;
    }
    

    其中关键的一步是调用Tcl_Init以加载文件"init.tcl"。(参见:Tcl 的初始化脚本文件"init.tcl")

    一处容易忽略的地方是开头的Tcl_FindExecutable(), 没有该调用的话,会发生内存访问异常。

    Tcl解释器中命令的执行

    /* 执行一段命令, 命令内容保存在 objPtr 中 */
    int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags);
    /************************************************
    * 第一次执行时,命令会被编译成字节码 
    ***********************************************/
    
    /* 执行一个文件, 相对于 source 语句 */
    int Tcl_EvalFile(Tcl_Interp *interp, const char	*fileName);
    
    /* 执行一段命令, 命令内容保存在字符串中 */
    int Tcl_Eval(Tcl_Interp *interp, const char *script );
    int Tcl_EvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags);
    /************************************************
    * 直接解析执行,不会编译成字节码 
    ***********************************************/
    /* 执行一条命令 */
    int Tcl_EvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj	**objv, int flags);
    
    

    附录:Makefile

    TCL_BASE     = /c/some/path/tcl
    TCL_BASE_WIN = c:/some/path/tcl
    
    ttcl: ttcl.c
    	gcc -o $@ -I$(TCL_BASE)/include ttcl.c $(TCL_BASE)/lib/tcl84.lib
    
    test:
    	ttcl.exe $(TCL_BASE_WIN)/lib/tcl8.4 test.tcl
    
    install:
    	cp $(TCL_BASE)/bin/tcl84.dll .
    
    标签:

      分享到:
      comments powered by Disqus

      29/34ms