0

我正在尝试创建自定义 tcl 通道并使用它来获取 tcl 解释器的输出。我添加了 Tcl_ChannelType 的几个函数的实现,但我遇到了段错误。

#include <tcl.h>
#include <iostream>

int driverBlockModeProc(ClientData instanceData, int mode) {
    std::cout << "driverBlockModeProc\n";
    return 0;
}

int driverCloseProc(ClientData instanceData, Tcl_Interp *interp) {
    std::cout << "driverCloseProc\n";
    return 0;
}

int driverInputProc(ClientData instanceData, char* buf, int bufSize, int *errorCodePtr) {
    std::cout << "driverInputProc\n";
    return 0;
}

int driverOutputProc(ClientData instanceData, const char* buf, int toWrite, int *errorCodePtr) {
    std::cout << "driverOutputProc\n";
    return 0;
}

int main() {

    Tcl_ChannelType *typePtr = new Tcl_ChannelType;

    typePtr->blockModeProc = driverBlockModeProc;
    typePtr->outputProc = driverOutputProc;
    typePtr->closeProc = driverCloseProc;
    typePtr->inputProc = driverInputProc;

    typePtr->seekProc = NULL;
    typePtr->setOptionProc = NULL;
    typePtr->getOptionProc = NULL;
    typePtr->watchProc = NULL;
    typePtr->getHandleProc = NULL;
    typePtr->close2Proc = NULL;
    typePtr->blockModeProc = NULL;
    typePtr->flushProc = NULL;
    typePtr->handlerProc = NULL;
    typePtr->wideSeekProc = NULL;
    typePtr->threadActionProc = NULL;

    ClientData data = new char[200];
    Tcl_CreateChannel(typePtr, "im_chanel", data, TCL_WRITABLE | TCL_READABLE);

}

我无法调试段错误,因为它的源不可用。我认为段错误是因为调用了一个为 NULL 的函数。我只需要使用通道来获取解释器的输出。哪些功能我不需要在这里实现,是解决问题的正确方向。

4

1 回答 1

2

在此级别工作时,建议您将源代码下载到 Tcl。我不确定您使用的是什么版本,但是可以追溯到很长一段时间的所有官方源代码分发都在SourceForge 文件分发系统上;选择与您拥有的版本完全匹配的版本。

创建自定义通道驱动程序并不容易。这涉及大量的复杂性,并且没有特别详细地记录通道驱动程序类型中的哪些“方法”是强制性的,哪些是可选的。(它们不是类中的 C++ 方法——Tcl 是纯 C 代码,原因太长,无法在此处介绍——但它们以概念上相似的方式运行。)

如果我们查看 的文档Tcl_CreateChannel,我们会看到(在该页面很长的地方)通道类型结构的定义。通道类型结构应该是静态分配的(Tcl 的实现非常强烈地假设它永远不会改变位置)并且必须将以下字段设置为有意义的东西:

  • typeName— 这是通道类型的名称,对调试很有用!
  • version— 这是通道类型的版本;您应该将其设置为目标源级别支持的最新版本。(建议您至少使用,TCL_CHANNEL_VERSION_2否则事情会变得相当复杂。)
  • closeProc close2Proc— 通道必须是可关闭的,但您有两种方法可以选择。双向通道应该使用close2Proc,但不是严格要求。
  • inputProc— 只有在阅读时才需要;注意正确处理。
  • outputProc——只有在你写作时才需要;注意正确处理。
  • watchProc— 调用以告诉通道驱动程序将自身安装到事件系统中,以便接收合适的事件(根据提供的位掩码的指示)。没有支持操作系统句柄的通道使用计时器事件,或者根本不实际生成事件(在这种情况下,从 的角度来看,它们永远不会变得可读或可写fileevent)。

查看您的代码,我发现您缺少一个watchProc. 我知道这很难看(说实话,编写通道驱动程序的人并不多,所以文档不是很难“测试”)但它确实是必要的。

于 2013-07-23T09:36:29.380 回答