tcl库:如何使用tcl_eval()来设置c代码tcl命令扩展的返回结果?

问题描述:

假设我实现了一个使用Tcl_CreateObjCommand注册的c代码编写的新tcl命令,并且在此c代码内部调用Tcl_Eval来评估包含代码的字符串,以创建关联数组并将其存储在变量tmp中。我如何设置这个用Tcl_eval()创建的tmp变量作为c函数的返回结果对象?tcl库:如何使用tcl_eval()来设置c代码tcl命令扩展的返回结果?

例子:

int MyCommand(
    ClientData clientData, 
    Tcl_Interp* interp, 
    int   argc, 
    char*  argv[]) 
{ 

    int rc = Tcl_Eval(interp, 
     "array set tmp [list {key1} {value1} {key2} {value2}]"); 
    if (rc != TCL_OK) { 
     return rc; 
    } 

    //??? 
    Tcl_SetObjResult(interp, ?? tmp variable from eval??); 
    return TCL_OK; 
} 

当我运行Tcl解释上述C的扩展,我希望看到这样的结果:

TCL> set x [MyCommand] 

TCL> puts "$x(key1)" 
value1 # Currently an Error and not set 

TCL> puts "$x(key2)" 
value2 # Currently and Error and not set 

在某种程度上,上述工程。只是不是我想要的。例如,如果I型:

TCL> set x [MyCommand] 

TCL> puts "$tmp(key1)" 
value1 # Its Works! Except, I didn't want to set a global variable tmp 

TCL> puts "$tmp(key2)" 
value2 # Its Works! Except, I didn't want to set a global variable tmp 

(也许它是一个“功能”设置TMP代替?)不管怎么说,我还是希望它使用PROC返回值一起工作的正确的方式“回报”机制。

从c-command-extension的Tcl_Eval内部调用Tcl_Eval()应该是合法的,因为“Tcl Library”的文档声明,对于tcl_eval,使嵌套调用评估其他命令是合法的。我只是不知道如何将Tcl_Eval的对象结果复制到c-extension过程的“return”对象。

我在这里看到两个问题。您不能将命令的返回值设置为数组的值,因为数组不是值。数组是由字符串索引的变量的集合。这是一个常见的误解。您可以返回数组元素的值。如果你想要一个适当的Tcl值的键/值映射,可以考虑一个字典。字典是值,可以作为命令的值返回。

第二个问题,你为什么使用Tcl_Eval()来创建一个数组。使用Tcl_SetVar()或其几个变体之一来构建数组要简单得多。

设置数组的推荐方法(假设您首先使用char*值)正在使用对Tcl_SetVar2(因为它将变量名称分为两部分)的调用。

Tcl_SetVar2(interp, "tmp", "key1", "value1", 0); 
Tcl_SetVar2(interp, "tmp", "key2", "value2", 0); 

惯用,你会使用传入作为参数传递给你的C命令实现作为参数的名称,使主叫方可以告诉你编写成什么样的变量,你要检查的结果太:

int MyCommand(
    ClientData clientData, 
    Tcl_Interp* interp, 
    int   argc, 
    char*  argv[]) 
{ 
    // Missing: check # of arguments 

    if (Tcl_SetVar2(interp, argv[1], "key1", "value1", 0) == NULL) 
     return TCL_ERROR; 
    if (Tcl_SetVar2(interp, argv[1], "key2", "value2", 0) == NULL) 
     return TCL_ERROR; 
    return TCL_OK; 
} 

你会然后调用,像这样:

MyCommand x 
# It has no meaningful result. 

puts $x(key1) 
puts $x(key2)