[英]Tcl Channel in GUI Application
我試圖將Tcl解釋器嵌入到C#GUI應用程序中,並且一切正常,甚至將NewFunction附加到TclCommand。 但是有一件事對我來說很難,我想將stdout,stdin,stderr重定向到某些TextBox。 我現在正在使用C ++,因為它更容易調試和編譯。 所以我用代碼
Tcl_Channel StdOut = Tcl_GetStdChannel(TCL_STDOUT);
Tcl_UnregisterChannel(interp,StdOut);
Tcl_Channel myStdOut = Tcl_CreateChannel(typePtr, "stdout",
NULL, TCL_READABLE | TCL_WRITABLE);
Tcl_RegisterChannel(interp, myStdOut);
Tcl_SetStdChannel(myStdOut, TCL_STDOUT);
注冊新的標准輸出,typePtr看起來像
typePtr->typeName = "stdout";
typePtr->version = TCL_CHANNEL_VERSION_2;
typePtr->getHandleProc = Tcl_MyDriverGetHandleProc;
typePtr->inputProc = Tcl_MyDriverInputProc;
typePtr->outputProc = Tcl_MyDriverOutputProc;
typePtr->flushProc = Tcl_MyDriverFlushProc;
typePtr->watchProc = Tcl_MyDriverWatchProc;
typePtr->closeProc = Tcl_MyDriverCloseProc;
typePtr->blockModeProc = Tcl_MyDriverBlockModeProc;
typePtr->seekProc = NULL;
typePtr->close2Proc = NULL;
typePtr->handlerProc = NULL;
typePtr->wideSeekProc = NULL;
typePtr->truncateProc = NULL;
typePtr->setOptionProc = NULL;
typePtr->getOptionProc = NULL;
typePtr->threadActionProc = NULL;
我連接的每個函數都返回TCL_OK或EINVAL(我從API知道)並將一些文本放入文件中,例如
int Tcl_MyDriverCloseProc(ClientData instanceData,
Tcl_Interp *interp) {
std::cout << "\n Tcl_MyDriverCloseProc\n";
file << "\n Tcl_MyDriverCloseProc\n";
file.flush();
return EINVAL;
}
我也使用std :: cout進行調試,但我不相信他。 當我編譯並運行任何內容時,stdout無法正常工作,例如
result:stderr file8adcd0 stdout stdin:
result::
我編譯的代碼是
Tcl_GetChannelNames(interp);
std::cout << "result:" << Tcl_GetStringResult(interp) << ":\n";
Tcl_Eval(interp, "puts SomeOneHelp");
std::cout << "result:" << Tcl_GetStringResult(interp) << ":\n";
我也無法創建自定義渠道並像這樣使用它
"puts myChannel pleHdeeNI"
當我用C ++完成時,我要在C#中創建函數,這會將3個TCL標准通道寫入TextBox,但是很容易。
Tcl通道級別低的文檔並不是最簡單的,因此查看示例代碼可能很有幫助。 Tk的實現中的generic/tkConsole.c
顯示了實際的stdout和stderr重定向是如何完成的。 特別是,需要非NULL值的字段是name
, version
, closeProc
(或close2Proc
), inputProc
, outputProc
, watchProc
和getHandleProc
,其中許多實際上可能是您創建的用於處理stdout和stderr的通道的虛擬對象。
但是,Tk控制台窗口小部件實際上並不支持提供真正的stdin(相反,它使用Tcl_Eval
在主解釋器中運行命令),而它提供的窗口小部件聲稱始終位於文件末尾。 這有點無濟於事。 另外, 所有通道都無法傳遞給子流程,因為它們在操作系統級別上沒有任何表示形式。 要解決該問題,將需要進行大量工作(也許使用匿名管道和工作線程以及一些技巧來處理不可避免的緩沖問題;使用Expect程序包之類的工具會做得多得多的工作,盡管代價是更加復雜)。
您可能想返回事物的非錯誤結果。 例如,始終從outputProc
返回0
會導致Tcl通道代碼的通用部分出現嚴重問題。 它假定這意味着事物已被阻塞,只是緩沖事物直到被告知它們已變得不受阻塞為止。 對於真正的吞咽一切嘗試,請返回與要求寫入的字節數相同的寫入字節數。 同樣,使closeProc
正常工作也很重要。 如果您沒有要處理的實例數據或要刪除的基礎OS資源,則可以在那里返回0
表示一切正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.