我使用Tcl_EvalFile
从C++程序运行Tcl脚本。我定义了一些自定义命令(使用Tcl_CreateCommand
(,所以当在文件中找到它们时,会调用回调,然后我可以运行一些C++代码(TclInvokeStringCommand
调用给Tcl_CreateCommand
的回调,回调类型为int (*executeCmd)( ClientData data, Tcl_Interp *interp, int argc, const char *argv[] )
(。
我想知道正在调用的回调函数中的脚本文件名和行号。
我可以使用((Interp*) interp)->scriptFile
获取脚本文件名。
但是,我无法获得脚本文件的行号。有没有办法检索(或以任何方式计算(?
信息仅通过info frame
命令在Tcl级别公开。(内部的C API太可怕了,它从来没有公开过。(这意味着你需要用Tcl_Eval()
:做这样的事情
// These can be cached safely per thread; reference management is a thing for another question
Tcl_Obj *scriptNameHandle = Tcl_NewStringObj("file", -1);
Tcl_Obj *lineNumberHandle = Tcl_NewStringObj("line", -1);
// How to actually get the information; I'm omitting error handling
Tcl_Eval(interp, "info frame -1");
Tcl_Obj *frameDict = Tcl_GetObjResult(interp);
Tcl_Obj *scriptNameObj = nullptr, *lineNumberObj = nullptr;
Tcl_DictObjGet(nullptr, frameDict, scriptNameHandle, &scriptNameObj);
Tcl_DictObjGet(nullptr, frameDict, lineNumberHandle, &lineNumberObj);
// Now we have to unbox the information
if (scriptNameObj != nullptr) {
const char *filename = Tcl_GetString(scriptNameObj);
// Do something with this info; COPY IT if you want to keep past the result reset
}
if (lineNumberObj != nullptr) {
int lineNumber = -1;
Tcl_GetIntFromObj(nullptr, lineNumberObj, &lineNumber);
// Do something with this info
}
// Release the result memory, i.e., the dictionary and its contents
Tcl_ResetResult(interp);
注意,file
和line
密钥都不保证存在;line
密钥通常在那里,但file
密钥只有在运行可以追溯到文件的代码时才在那里,即,追溯到Tcl_EvalFile()
和相关的代码。