我试图将 Tcl 解释器嵌入到 C# GUI 应用程序中,并且一切正常,甚至 AttachingNewFunction 到 TclCommand。但有一件事对我来说很难,我想将 stdout、stdin、stderr 重定向到一些 TextBox'es。我现在使用 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 进行调试,但我不相信他。当我编译&运行什么都没有发生时,标准输出不起作用,结果是例如
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'es,但它很容易。