Tcl扩展:理解和使用ClientData

Tcl扩展:理解和使用ClientData,c,tcl,C,Tcl,我正在努力更新旧软件(编写为基于Tcl/Tk 8.3构建),以便它能够基于更现代的发行版构建。我借此机会学习C和Tcl,这两个我在项目开始时从未编程过的东西。所以,我是个新手 在学习Tcl API时,我最困惑的事情之一是ClientData。API中的许多函数都将其作为参数,但C扩展几乎从不使用它。我的印象是,很少使用全局定义: 整个extension ClientData用于希望 发布自己的存根表。。。其他扩展可以基于此进行构建。 这是一件非常难得的事情;如果没有,请在NULL处离开 我想要它

我正在努力更新旧软件(编写为基于Tcl/Tk 8.3构建),以便它能够基于更现代的发行版构建。我借此机会学习C和Tcl,这两个我在项目开始时从未编程过的东西。所以,我是个新手

在学习Tcl API时,我最困惑的事情之一是
ClientData
。API中的许多函数都将其作为参数,但C扩展几乎从不使用它。我的印象是,很少使用全局定义:

整个extension ClientData用于希望 发布自己的存根表。。。其他扩展可以基于此进行构建。 这是一件非常难得的事情;如果没有,请在NULL处离开 我想要它

因此,它基本上是一个
void
参数,您需要在内部键入cast或handle。但代码中有些地方需要与ClientData交互(例如,对于空闲进程,如下所示):

编译时,强制转换为整数会导致以下警告:

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
我的主要困惑是
(ClientData)G->num
——我不明白我要做什么,因为我不知道ClientData是什么东西。如果我查看Tcl来源,我没有发现清晰性:

tclCompile.h:220:typedef ClientData (AuxDataDupProc)  (ClientData clientData);
tclInt.h:2520:typedef ClientData (TclFSGetCwdProc2)(ClientData clientData);
tclOOInt.h:73:typedef ClientData (TclOO_PmCDCloneProc)(ClientData clientData);
最后几点:这些编译器警告在我开始对代码进行任何更新之前就存在了。该程序似乎在旧系统上工作,原始代码在旧系统上编译和运行。所以,我不确定这个警告是否有什么意义。。。但这让我很害怕,只要我花时间在代码上,学习C和Tcl,我就希望了解它的真相


如果我没有提供足够的相关信息,请提前道歉。我很乐意提供更多信息,但这是我目前在回答一个好问题方面所做的最大努力。

一般来说,
ClientData
的意思是“Tcl承诺不会为您解释的指针”,它实际上总是会在回调中返回给您的。将其视为
void*
(这就是它的
typedef

您提到的答案是专门讨论
Tcl\u PkgRequireEx
函数,其中
ClientData
内容用于传递对存根表的引用。你可以用这个来通过你自己的,但它相当复杂。这是一件非常罕见的事情;大多数人从未接触过这些秘密

一般来说,更常见的是将其与
Tcl\u CreateCommand
Tcl\u CreateObjCommand
关联使用。在这里,
clientData
参数是一个指针,当调用创建的命令时,它将被传递回实现回调;这对于表示类实例之类的命令非常有用。Tcl将其用于程序之类的事情;
proc
命令使用
clientData
将指向描述主体脚本(和其他内容)的结构的指针传递给实现过程的C函数。如果您对Tk略知一二,那么,
clientData
被广泛用于将低级句柄传递给窗口结构

使用
Tcl\u DoWhenIdle
,它又是一个指针被交给回调函数。当然,回调函数的签名不同,但基本思想相同


<>如果TCL提供C++ ++ API,那么它可能会有点不同,因为它可以用该语言来讨论指向实例方法的指针。但是Tcl的API是C API,所以一切都必须像这样工作。

使用变量
g
g
是一种非常糟糕的编程实践,可能会/将导致误解和维护噩梦。我同意——我活在噩梦中。我也在努力改进这些方面。谢谢你。把它想象成一个回调是有帮助的。
tclCompile.h:220:typedef ClientData (AuxDataDupProc)  (ClientData clientData);
tclInt.h:2520:typedef ClientData (TclFSGetCwdProc2)(ClientData clientData);
tclOOInt.h:73:typedef ClientData (TclOO_PmCDCloneProc)(ClientData clientData);