如何 return 脚本变量中的 Tcl 字典?
How to return a Tcl dictionary in a script variable?
我在查询数据库后有一个 SQL 回调函数,然后我试图将该数据填充到 TCL 字典中,以便我可以在 TCL 脚本中捕获它。
我有这个回调函数,它会为每个 select 调用,并将列添加为键及其值。我将 Tcl_Interp* 作为数据参数传递。
int callback(void *interp, int argc, char **argv, char **azColName)
{
int i = 0;
Tcl_Obj *dictPtr = Tcl_NewDictObj();
for (i = 0; i < argc; i++) {
Tcl_Obj *key = Tcl_NewStringObj(azColName[i], -1);
Tcl_Obj *value = Tcl_NewStringObj((argv[i] ? argv[i] : "null"), -1);
Tcl_DictObjPut((Tcl_Interp*) interp, dictPtr, key, value);
}
return TCL_OK;
}
问题是当运行这个命令像...
set res [mycommand getrow]
foreach i $res {
puts "i = $i"
}
我看到确实调用了回调并添加了正确的 key/val,但打印的结果是...
i = 0
我在这里遗漏了什么吗?我期待我的密钥(列)和 val 的(行)被列出。
您缺少对 Tcl_SetObjResult
的调用,这可能最好紧接在函数 returns TCL_OK
.
之前
int callback(void *interp, int argc, char **argv, char **azColName)
{
int i = 0;
Tcl_Obj *dictPtr = Tcl_NewDictObj();
for (i = 0; i < argc; i++) {
Tcl_Obj *key = Tcl_NewStringObj(azColName[i], -1);
Tcl_Obj *value = Tcl_NewStringObj((argv[i] ? argv[i] : "null"), -1);
// Should handle refcounts correctly for keys
Tcl_IncrRefCount(key);
// Don't need to pass an interp; that's just for errors
Tcl_DictObjPut(NULL, dictPtr, key, value);
Tcl_DecrRefCount(key);
}
// This is the critical line
Tcl_SetObjResult((Tcl_Interp*) interp, dictPtr);
return TCL_OK;
}
为什么Tcl_DictObjPut
这里不需要interp?我们可以(简单地)证明它永远不会产生错误; dictPtr
参数始终是一个格式正确的字典(并且未共享,但弄错会导致恐慌)。
我在查询数据库后有一个 SQL 回调函数,然后我试图将该数据填充到 TCL 字典中,以便我可以在 TCL 脚本中捕获它。
我有这个回调函数,它会为每个 select 调用,并将列添加为键及其值。我将 Tcl_Interp* 作为数据参数传递。
int callback(void *interp, int argc, char **argv, char **azColName)
{
int i = 0;
Tcl_Obj *dictPtr = Tcl_NewDictObj();
for (i = 0; i < argc; i++) {
Tcl_Obj *key = Tcl_NewStringObj(azColName[i], -1);
Tcl_Obj *value = Tcl_NewStringObj((argv[i] ? argv[i] : "null"), -1);
Tcl_DictObjPut((Tcl_Interp*) interp, dictPtr, key, value);
}
return TCL_OK;
}
问题是当运行这个命令像...
set res [mycommand getrow]
foreach i $res {
puts "i = $i"
}
我看到确实调用了回调并添加了正确的 key/val,但打印的结果是...
i = 0
我在这里遗漏了什么吗?我期待我的密钥(列)和 val 的(行)被列出。
您缺少对 Tcl_SetObjResult
的调用,这可能最好紧接在函数 returns TCL_OK
.
int callback(void *interp, int argc, char **argv, char **azColName)
{
int i = 0;
Tcl_Obj *dictPtr = Tcl_NewDictObj();
for (i = 0; i < argc; i++) {
Tcl_Obj *key = Tcl_NewStringObj(azColName[i], -1);
Tcl_Obj *value = Tcl_NewStringObj((argv[i] ? argv[i] : "null"), -1);
// Should handle refcounts correctly for keys
Tcl_IncrRefCount(key);
// Don't need to pass an interp; that's just for errors
Tcl_DictObjPut(NULL, dictPtr, key, value);
Tcl_DecrRefCount(key);
}
// This is the critical line
Tcl_SetObjResult((Tcl_Interp*) interp, dictPtr);
return TCL_OK;
}
为什么Tcl_DictObjPut
这里不需要interp?我们可以(简单地)证明它永远不会产生错误; dictPtr
参数始终是一个格式正确的字典(并且未共享,但弄错会导致恐慌)。