2013-04-26 88 views
0
static int 
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[]) 
{ 
//  Tcl_DeleteInterp(interp); 
//  Tcl_Finalize(); 
     return TCL_OK; 
} 

int main() { 
    Tcl_Interp *interp = Tcl_CreateInterp(); 
    Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL); 

    Tcl_Eval(interp, "exit ; puts 11111111"); 
    std::cout << "22222222222" << std::endl; 
    return 0; 
} 

我需要处理的TCL解释的exit命令评价。默认情况下,它试图删除自己还呼吁std::exit封闭整个program.It是不是我想要的,所以我想通过自定义PROC来取代它。我不需要在退出处理程序proc中删除解释器(以后我可以这样做),只需要它不会在exit命令后继续执行求值命令。如何让tcl解释器在退出命令后不再继续?

在这段代码中,我需要改变MyReplacementExit PROC不知何故,所以11111111不进行打印,但 22222222222并打印。

它可以通过从MyReplacementExit proc返回TCL_ERROR来实现,但是我无法区分其他错误情况。

+0

你尝试调用['Tcl_CancelEval'](http://www.tcl.tk/man/tcl8.6/TclLib/Cancel .htm)从你的'exit'替换? – 2013-04-26 16:30:19

+0

@JohannesKuhn这可能是一个解决方案,但我的TCL版本是8.4,它不支持Tcl_CancelEval – Ashot 2013-04-26 16:36:20

+0

有关MyReplacementExit返回TCL_BREAK或TCL_CONTINUE什么?它会在你重新定义的“退出”之后跳过执行命令吗? – 2013-04-26 17:02:34

回答

1

让你更换为exit删除解释(这样就不会执行进一步的命令,但实际上并没有立即删除的数据结构,因为它仍然在使用),并重要,包装与调用Tcl_Eval致电Tcl_PreserveTcl_Release。如果可以避免,请不要拨打Tcl_Finalize;那是因为当你要从内存中卸载Tcl库时,可能会非常棘手(坦白地说,退出这个过程比较容易)。

下面是如何与你的代码(改编)做到这一点:

static int 
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[]) 
{ 
    Tcl_DeleteInterp(interp); // <------------------ 
    return TCL_OK; 
} 

int main() { 
    Tcl_Interp *interp = Tcl_CreateInterp(); 
    Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL); 

    Tcl_Preserve(interp);  // <------------------ 
    Tcl_Eval(interp, "exit ; puts 11111111"); 
    Tcl_Release(interp);  // <------------------ 
    std::cout << "22222222222" << std::endl; 
    return 0; 
} 

要知道,你应该访问解释在所有,因为它可能已经被破坏了Tcl_Release后(如在这个时候,内存释放并随意乱扔垃圾)。如果您需要检索结果并使用它们(例如将其打印出来),请事先进行操作。

注意,在这种特定的情况下,你不需要保存/释放对;你的代码实际上并没有在Tcl_Eval(内部自行保存/发布)之后触及解释器。


如果你不想让解释器终止,那就更棘手了。在8.4干净的方法可能是引发自定义异常代码(即任何比TCL_CONTINUE更大),但没有保证,它将对任意代码工作作为Tcl的catch命令还可以捕获它。如果你确实处于这种情况,那么创建一个解释器,在子interp中运行任意代码,并在脚本结尾处将其撕下,实际上会更容易;那么您可以放弃该解释器而不会丢失很多上下文。事实上,你可以这样做:

Tcl_Preserve(interp); 
if (Tcl_Eval(interp, theScriptToEval) != TCL_OK) 
    // Handle unexpected errors here 
if (!Tcl_InterpDeleted(interp)) 
    Tcl_DeleteInterp(interp); 
Tcl_Release(interp); 

是的,这将意味着你要保持与你所做成立解释非常小的量;你可能不会想尝试把这种上一次中断毫秒...

相关问题