在C程序中重复使用Tcl解释器 [英] Using the TCL interpreter repeatedly inside a C program

查看:28
本文介绍了在C程序中重复使用Tcl解释器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望重复使用一个c程序,多次运行Tcl解释器。由于复杂的原因,我需要它是一个纯C程序,而不是作为共享对象嵌入的东西。例如,我希望运行这个简单的Tcl程序tryMe.tcl两次:

prtstr "Test from tryMe.tcl"

prtstr是我编写的Tcl函数,目前只写入stdout。下面是尝试两次解释tryMe.tcl程序的c代码。

我在Linux下编译如下程序:

$ gcc -c try.c; gcc -o try try.o -ltcl; 

并按如下方式运行:

$ ./try tryMe.tcl

并且我得到零输出。我做错了什么?还需要执行一些步骤来重置Tcl解释器,以使其每次都是新鲜的。

#define _GNU_SOURCE
#include <tcl/tcl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int PrintStrObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
  char     *str;
  int      len;
  Tcl_Obj *objPtr;
  int i;
  if (objc != 2) {
    Tcl_WrongNumArgs(interp, 1, objv, "value");
   return TCL_ERROR;
  }
  objPtr = objv[1];

  str = Tcl_GetStringFromObj(objPtr, &len);
  if (str[0] == '')
    return TCL_ERROR;

  printf("len: %d, str: %s
", len, str);
  return TCL_OK;
}

int Tcl_AppInit(Tcl_Interp* interp)
{
  if (Tcl_Init(interp) == TCL_ERROR)
    return TCL_ERROR;
  Tcl_CreateObjCommand(interp,"prtstr", PrintStrObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
  return TCL_OK;
}

int main(int argc, char *argv[])
{
  char *cmd = NULL;
  Tcl_Interp * interp = Tcl_CreateInterp();

  Tcl_AppInit(interp);

  asprintf(&cmd, "%s -x -y -z", argv[1]);
  Tcl_Eval(interp, cmd);
  free(cmd);
  asprintf(&cmd, "%s -q -r -s 2", argv[1]);
  Tcl_Eval(interp, cmd);
  exit(0);
}

非常感谢!

推荐答案

感谢您提供指向Tcler的Wiki的指针。这很有帮助。我不明白Tcl_Eval(interp,script)中的script不是文件名,而是包含Tcl程序的字符串。所以这个程序使用TCL_Evalfile(),我还希望能够将命令行参数传递给Tcl程序。我了解了如何使用Tcl_MainEx()的Tcl源代码。下面是一个程序,它可以做我想要的事情。我还发现,多个调用Tcl_EvalFile确实会保留状态,因此如果我想要解释器的新值,我每次都必须删除旧的值并创建新的值。

#include <tcl/tcl.h>
#include <stdio.h>
#include <stdlib.h>

int PrintStrObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
  char     *str;
  int      len;
  Tcl_Obj *objPtr;
  int i;
  if (objc != 2) {
    Tcl_WrongNumArgs(interp, 1, objv, "value");
    return TCL_ERROR;
  }
  objPtr = objv[1];

  str = Tcl_GetStringFromObj(objPtr, &len);
  if (str[0] == '')
    return TCL_ERROR;

  printf("len: %d, str: %s
", len, str);
  return TCL_OK;
}

int Tcl_AppInit(Tcl_Interp* interp)
{
  if (Tcl_Init(interp) == TCL_ERROR)
    return TCL_ERROR;
  Tcl_CreateObjCommand(interp,"prtstr", PrintStrObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
  return TCL_OK;
}

int main(int argc, char **argv)
{
  char       *script = argv[1];
  Tcl_Obj    *argvPtr;
  Tcl_FindExecutable(script);

  Tcl_Interp *interp = Tcl_CreateInterp();
  if (interp == NULL) {
    fprintf(stderr,"Cannot create TCL interpreter
");
    exit(-1);
  }

  if (Tcl_AppInit(interp) != TCL_OK)
    return TCL_ERROR;

  Tcl_SetVar2Ex(interp, "argv0", NULL, Tcl_NewStringObj(script,-1), TCL_GLOBAL_ONLY);
  argc -= 2;
  argv += 2;
  Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);
  argvPtr = Tcl_NewListObj(0, NULL);
  while (argc--) 
    Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj(*argv++, -1));
  Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

  if (Tcl_EvalFile(interp, script) != TCL_OK)
    return TCL_ERROR;

  exit(0);
}


这篇关于在C程序中重复使用Tcl解释器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆