GUI应用程序中的Tcl通道

时间:2013-08-26 12:00:58

标签: c# c++ user-interface tcl channel

我试图将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进行调试,但我不相信他。 当我编译和运行没有任何事情发生时,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'es,但它很容易。

1 个答案:

答案 0 :(得分:1)

低级别Tcl通道的文档并不是最简单的,因此查看示例代码可能具有指导意义。 Tk实现中的generic/tkConsole.c显示了如何完成真正的stdout和stderr重定向。特别是,需要非NULL值的字段是nameversioncloseProc(或close2Proc),inputProcoutputProcwatchProcgetHandleProc,其中许多实际上可能是您为处理stdout和stderr创建的通道的假人。

但是,Tk控制台小部件不支持实际提供真正的标准输入(相反,它使用Tcl_Eval在主解释器中运行命令)而它提供的那个只声称总是在结束时-文件。这有点像暴乱。此外,没有任何通道完全能够传递给子进程,因为它们在OS级别没有任何表示。修复这将需要更多的工作(可能使用匿名管道和工作线程和技巧来处理不可避免的缓冲问题;使用像Expect包这样的东西会做更完整的工作,但代价甚至更多< / em>复杂性)。

您可能希望从事物中返回非错误结果。例如,始终从0返回outputProc将导致Tcl通道代码的通用部分出现严重问题;它假设这意味着事情被阻止,只是缓解一切,直到它被告知它们已被解除阻塞。对于真正的吞咽 - 一切都先尝试,返回写入的字节数与您要写入的字节数相同。同样,使closeProc正常工作也很重要;如果您没有要处理的实例数据或基础OS资源,那么您只需返回0即可确定一切正常。