Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
tcl库:如何使用tcl_eval()设置c代码tcl命令扩展的返回结果?_C_Tcl - Fatal编程技术网

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

tcl库:如何使用tcl_eval()设置c代码tcl命令扩展的返回结果?,c,tcl,C,Tcl,假设我实现了一个用c代码编写的新tcl命令,该命令是我使用tcl_CreateObjCommand注册的,在这个c代码中,我调用tcl_Eval来计算一个字符串,该字符串包含创建关联数组并将其存储在变量tmp中的代码。如何将这个用Tcl_eval()创建的tmp变量设置为c函数的返回结果对象 例如: int MyCommand( ClientData clientData, Tcl_Interp* interp, int argc, cha

假设我实现了一个用c代码编写的新tcl命令,该命令是我使用tcl_CreateObjCommand注册的,在这个c代码中,我调用tcl_Eval来计算一个字符串,该字符串包含创建关联数组并将其存储在变量tmp中的代码。如何将这个用Tcl_eval()创建的tmp变量设置为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-command-extension的Tcl_Eval内部调用Tcl_Eval()应该是合法的,因为“Tcl库”的文档说明,对于Tcl_Eval,进行嵌套调用以评估其他命令是合法的。我只是不知道如何将对象结果从Tcl_Eval复制到c扩展过程的“return”对象

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


第二个问题是为什么要使用Tcl_Eval()创建数组。使用Tcl_SetVar()或其多种变体之一构建阵列要简单得多。

我在这里看到两个问题。不能将命令的返回值设置为数组的值,因为数组不是值。数组是由字符串索引的变量集合。这是一个常见的误解。可以返回数组元素的值。如果您想要一个正确的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,
字符*argv[]
{
//缺少:参数的检查
if(Tcl_SetVar2(interp,argv[1],“key1”,“value1”,0)==NULL)
返回TCL_错误;
if(Tcl_SetVar2(interp,argv[1],“key2”,“value2”,0)==NULL)
返回TCL_错误;
返回TCL_OK;
}
然后你会这样称呼它:

MyCommand x
# It has no meaningful result.

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

设置数组的推荐方法(假设您首先使用的是
char*
值)是调用
Tcl\u 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,
字符*argv[]
{
//缺少:参数的检查
if(Tcl_SetVar2(interp,argv[1],“key1”,“value1”,0)==NULL)
返回TCL_错误;
if(Tcl_SetVar2(interp,argv[1],“key2”,“value2”,0)==NULL)
返回TCL_错误;
返回TCL_OK;
}
然后你会这样称呼它:

MyCommand x
# It has no meaningful result.

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