c++ - 创建自定义 tcl channel 驱动程序时出现段错误

标签 c++ tcl channel

我正在尝试创建自定义 tcl channel 并使用它来获取 tcl Interpreter 的输出。我添加了 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 函数。我只需要使用 channel 来获取解释器的输出。哪些功能我不需要在这里实现,它是解决问题的正确方向。

最佳答案

建议您在此级别上工作时将源代码下载到 Tcl。我不确定您使用的是什么版本,但是源代码的所有官方发行版都在 the SourceForge file distribution system 上。 ;为您的版本选择完全匹配的版本。

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

如果我们查看 Tcl_CreateChannel 的文档,我们看到(在该页面下方相当长的一段距离) channel 类型结构的定义。 channel 类型结构应该静态分配(Tcl 的实现非常强烈地假设它从不改变位置)并且必须将以下字段设置为有意义的内容:

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

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

关于c++ - 创建自定义 tcl channel 驱动程序时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17803588/

相关文章:

c++ - 带有模型的 Qt TableView 包含指向自定义类的指针

c++ - 在对象声明上下文中获取此类型

Golang channel 让程序无限期等待

api - TLS sslv3 握手错误

go - 从 Tcl 脚本调用 golang 函数

go - 为什么在两个 channel 上选择的时间比在单 channel 上选择的时间慢得多?

smtp - System.Net.Mail.SmtpException : Service not available,关闭传输 channel 。服务器响应为: 4. 4.2

c++ - ISO C++ 说这些是模棱两可的,运算符重载

c++ - 可以使用临时的 stringstream 对象吗?

正则表达式循环查找每个查询 TCL 的第一个实例