c - TCL-C API : Tcl_LinkVar function use

标签 c tcl

我正在尝试将一个 Tcl 变量链接到一个 C 变量,以便在 C 线程创建期间将指针传递给最新的指针并拥有一个 TCL-C 线程共享变量(我不认为我可以使用 native TCL 线程共享变函数)。 我很难链接这两个变量。 这是我的做法:

#Tcl code, calling the C function:
set linkedVar 98
puts "linkedVar: $linkedVar"
load [file join [pwd] libCextension[info sharedlibextension]]
set threadId [createThreadC]
puts "Created thread n° $threadId"
puts "linkedVar: $linkedVar"

createThreadC 函数创建一个 C 线程,返回其 ID 并尝试使用 linkedVar 创建一个链接。

// C function called by Tcl
static int
createThreadC_Cmd(
    ClientData cdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int linkedVar=2;
    Tcl_LinkVar(interp, "linkedVar", (char *) &linkedVar, TCL_LINK_INT);
    linkedVar=1;
    ...
    # Thread creation, return Tcl object with thread ID
    ...
    return TCL_OK;  
}

这是输出:

linkedVar: 98
Created thread n° -1227199680
linkedVar: 35

linkedVar 值已更改,因为 C 程序必须这样做,但它存储了错误的变量,应该是 1 而不是 35。 是 (char *) &linkedVar 转换错了吗?

最佳答案

您正在正确使用 Tcl_LinkVar 几乎;您的原始代码类型正确。但这不是问题所在!

问题是您在 Tcl 解释器(具有相当长的生命周期)和 C 堆栈上具有短生命周期的变量之间进行链接。在 createThreadC_Cmd 之后,链接指向未使用的堆栈,并且通常会在之后立即用于其他事情。这是正式的未定义行为,而且非常糟糕。您需要做的是确保 C 变量的生命周期至少与解释器的生命周期一样长。

最简单的修复方法是使用全局(或static 局部)变量。唯一的缺点是同一变量将在对 createThreadC_Cmd 的所有调用之间共享;有时这根本不是问题,但我怀疑你的情况并非如此。因此,您需要在别处分配一些空间。如果您不希望您创建的解释器消失,那么最便宜的方法就是使用 malloc 获得一点空间,然后将链接指向该空间;然后你可以泄漏内存并停止担心它(这是不干净的,但很容易做到)。如果你想清理,你做几乎相同的事情,但注册一个适当的关闭 Hook ,释放内存;根据实际消失的情况,Tcl 具有三种关闭 Hook :

  1. Interpreter 关闭 Hook 是使用 Tcl_CallWhenDeleted
  2. 创建的
  3. Thread 关闭 Hook 是使用 Tcl_CreateThreadExitHandler
  4. 创建的
  5. Process/library shutdown hooks 是用 Tcl_CreateExitHandler 创建的(你不需要它来删除内存,除非你需要非常干净;警告,很难在调用它们时立即删除内存)。

我不太确定哪个适合你;这取决于您共享变量的范围。 (我希望您不打算跨线程共享它;设计上不会很好地工作。)

关于c - TCL-C API : Tcl_LinkVar function use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12315049/

相关文章:

c - 从一个 header 到另一个 header 中的结构的结构

shell - 使用 TCL 的 tk_getOpenFile 压缩多个文件

unix - 为什么 grep 需要这么多时间?

tcl - TCL 中的 FIFO 文件

c - 动态分配二维数组以匹配 LINES 和 COLS

当定义包含参数时调用不带参数的函数

c++ - 循环链表算法

c - 是否可以重复getopt

java - 文件开头的附加 "2000"字符串([32 30 30 30] 字节)

python - 行号和语法突出显示在不同选项卡上不起作用