首页 > 解决方案 > 如何在脚本变量中返回 Tcl 字典?

问题描述

查询数据库后,我有一个 SQL 回调函数,然后我试图将该数据填充到 TCL 字典中,以便可以在 TCL 脚本中捕获它。

我有这个回调函数,它会为每个选择调用,并将列作为键添加它的值。我将 Tcl_Interp* 作为数据 arg 传递。

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"
}

我看到确实调用了回调并且正在添加正确的键/值,但是打印的结果是......

i = 0

我在这里错过了什么吗?我期待我的键(列)和 val 的(行)被列出。

标签: tclinterpreter

解决方案


您错过了对 的调用Tcl_SetObjResult,这可能最好在函数返回之前立即调用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参数始终是一个格式良好的字典(并且不共享,但弄错会导致恐慌)。


推荐阅读