2012-05-31 50 views
3

的Tcl 8.4Tcl的API如何从Tcl的

获取列表在我的Tcl脚本来:

set foo1 false 
set foo2 "yes" 
set foo3 [list item1 item2 item3] 

有一个API来得到这样foo1或foo2的标量。例如:Tcl_GetVar(tcl_interp, string("foo1").c_str(), flags)。我想知道是否有任何API可以从Tcl获取列表(如foo3)?

+1

注TCL的API是一个C API,而不是C++。这意味着它有许多成语,从C++的角度来看,它们显然很笨拙。 AFAIK,没有人制作出Tcl API的权威C++改编版本(或者至少他们还没有完成并保持它)。 –

回答

6

这是一个两阶段的事情。您首先使用Tcl_GetVar系列函数中的一个获取该值,然后获取您感兴趣的列表(通常为Tcl_SplitListTcl_ListObjGetElements)。

至于更具体的例子:

////// FETCH FROM VARIABLE ////// 
// The NULL is conventional when you're dealing with scalar variable, 
// and the 0 could be TCL_GLOBAL_ONLY or 
Tcl_Obj *theList = Tcl_GetVar2Ex(interp, string("foo1").c_str(), NULL, TCL_LEAVE_ERR_MSG); 
if (theList == NULL) { 
    // Was an error; message in interpreter result... 
} 

////// EXTRACT ELEMENTS ////// 
int objc; 
Tcl_Obj **objv; 
if (Tcl_ListObjGetElements(interp, theList, &objc, &objv) == TCL_ERROR) { 
    // Not a list! error message in interpreter result... 
} 

////// WORK WITH VALUES ////// 
for (int i=0 ; i<objc ; i++) { 
    const char *value = Tcl_GetString(objv[i]); 
    // Whatever... 
} 
+1

如果您使用旧的纯粹基于字符串的API,则最终将使用['Tcl_SplitList'](http://www.tcl_tk/man/tcl8.6/TclLib/SplitList.htm)。这有一个“不寻常”的功能,因为你必须使用'Tcl_Free'这个字符串数组,这真的不是很方便。它也是**方式比基于'Tcl_Obj'的API慢。 –

1

我不确定,但Tcl_ListObjGetElements看起来像你想要的。或者,Tcl_ObjGetVar2将返回一个Tcl_Obj,然后您可以使用Tcl API的其余部分处理列表对象。

+0

'Tcl_GetVar2Ex'通常是最方便的。 –

-1

嗨,我已经发现含有对付列表中的一个例子这个有用的链接:

参考:: https://www.tcl.tk/man/tclx8.2/TclCommandWriting.3.html

int Tcl_LreverseObjCmd(notUsed, interp, objc, objv) 
    ClientData notUsed;    /* Not used. */ 
    Tcl_Interp *interp;    /* Current interpreter. */ 
    int   objc;     /* Number of arguments. */ 
    Tcl_Obj  **obj;     /* Argument strings. */ 
{ 
    int listObjc, lowListIndex, hiListIndex; 
    Tcl_Obj **listObjv; 
    char *temp, *resultList; 
    Tcl_Obj **newListObjv; 

    /* Verify argument count. Since we take only one argument, argument 
    * count must be 2 (command plus one argument). 
    */ 
    if (objc != 2) 
     return TclX_WrongArgs (interp, objv [0], "list"); 

    /* Create an object to handle the new list we're creating */ 
    newListObjv = Tcl_NewObj(); 

    /* Crack the list at objv[1] into its own count and array of object 
    * pointers. 
    */ 
    if (Tcl_ListObjGetElements (interp, objv[1], &listObjc, &listObjv) != TCL_OK) { 
     return TCL_ERROR; 
    } 

    /* For each element in the source list from last to first, append an 
    * element to the new list. 
    */ 
    for (listIndex = listObjc - 1; listIndex >= 0; listIndex--) { 
     Tcl_ListObjAppendElement (interp, newListObjv, listObjv[listIndex]); 
    } 
FIX: NEED TO RETURN THE LIST. 
    return TCL_OK; 
}