2013-04-26 89 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); 

是的,這將意味着你要保持與你所做成立解釋非常小的量;你可能不會想嘗試把這種上一次中斷毫秒...

相關問題