2017-10-19 110 views
0

假設我實現了一個使用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」對象。

回答

2

我在這裏看到兩個問題。您不能將命令的返回值設置爲數組的值,因爲數組不是值。數組是由字符串索引的變量的集合。這是一個常見的誤解。您可以返回數組元素的值。如果你想要一個適當的Tcl值的鍵/值映射,可以考慮一個字典。字典是值,可以作爲命令的值返回。

第二個問題,你爲什麼使用Tcl_Eval()來創建一個數組。使用Tcl_SetVar()或其幾個變體之一來構建數組要簡單得多。

2

設置數組的推薦方法(假設您首先使用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)