假设我实现了一个新的tcl命令,它是用c代码编写的,我使用Tcl_CreateObjCommand注册了它,在这个c代码中,我调用Tcl_Eval来计算一个字符串,该字符串包含创建关联数组的代码,并将其存储在变量tmp中。如何将这个用Tcl_eval()创建的临时变量设置为c函数的返回结果对象?
示例:
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;
}当我使用上面的C扩展运行Tcl解释器时,我希望看到这样的结果:
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在某种程度上,上面的方法是有效的。只是不是我想要的方式。例如,如果我键入:
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 "return“机制返回值。
从c命令扩展的Tcl_Eval内部调用Tcl_Eval()应该是合法的,因为"Tcl库“的文档指出,对于tcl_eval,进行嵌套调用以评估其他命令是合法的。我只是不知道如何将对象结果从Tcl_Eval复制到c-extension过程的“返回”对象中。
发布于 2017-10-20 10:01:41
我在这里看到了两个问题。您不能将命令的返回值设置为数组的值,因为数组不是值。数组是由字符串索引的变量集合。这是一个常见的误解。您可以返回数组元素的值。如果需要一个适当的Tcl值的键/值映射,可以考虑使用字典。字典是值,可以作为命令的值返回。
第二个问题是为什么要使用Tcl_Eval()来创建数组。使用Tcl_SetVar()或它的几个变体之一来构建数组要简单得多。
发布于 2017-10-20 22:40:45
设置数组的推荐方法(假设您首先使用的是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)https://stackoverflow.com/questions/46837131
复制相似问题