首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >tcl库:如何使用tcl_eval()来设置c代码tcl命令扩展的返回结果?

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

Stack Overflow用户
提问于 2017-10-20 03:07:15
回答 2查看 623关注 0票数 0

假设我实现了一个新的tcl命令,它是用c代码编写的,我使用Tcl_CreateObjCommand注册了它,在这个c代码中,我调用Tcl_Eval来计算一个字符串,该字符串包含创建关联数组的代码,并将其存储在变量tmp中。如何将这个用Tcl_eval()创建的临时变量设置为c函数的返回结果对象?

示例:

代码语言:javascript
复制
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解释器时,我希望看到这样的结果:

代码语言:javascript
复制
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

在某种程度上,上面的方法是有效的。只是不是我想要的方式。例如,如果我键入:

代码语言:javascript
复制
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过程的“返回”对象中。

EN

回答 2

Stack Overflow用户

发布于 2017-10-20 10:01:41

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

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

票数 2
EN

Stack Overflow用户

发布于 2017-10-20 22:40:45

设置数组的推荐方法(假设您首先使用的是char*值)是使用对Tcl_SetVar2的调用(之所以这样命名,是因为它将变量名分为两部分)。

代码语言:javascript
复制
Tcl_SetVar2(interp, "tmp", "key1", "value1", 0);
Tcl_SetVar2(interp, "tmp", "key2", "value2", 0);

按照惯例,您可以将名称作为参数传递给C命令实现作为参数,这样调用者就可以告诉您要写入哪个变量,并且您也希望检查结果:

代码语言:javascript
复制
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;
}

然后你可以这样叫它:

代码语言:javascript
复制
MyCommand x
# It has no meaningful result.

puts $x(key1)
puts $x(key2)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46837131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档