如何为'ensemble'命令创建C / C ++代理

时间:2016-09-27 09:39:27

标签: tcl

我需要在tcl解释器中注册的每个命令之前调用一个代理函数(C / C ++)。对于临时命令,它很简单,我得到Tcl_CmdInfo,记住它,并将我的代理函数设置为Tcl_CmdInfoobjProc字段。当我的代理被呼叫时,我会按照我的需要进行操作,然后从原始objProc拨打Tcl_CmdInfo。它运作正常。

问题是当我为他们调用info时,整体命令(dictTcl_SetCommandInfo等)会停止为'整体'。它们工作正常,但不能被'namespace ensemble'修改。有什么想法吗?

PS。跟踪不是解决方案:它慢几倍,我不能接受它。

1 个答案:

答案 0 :(得分:0)

执行此操作的官方API是跟踪。特别是,它禁用字节码编译,因此命令跟踪可以正确地用于字节码编译命令。是的,它的速度较慢,但​​这就是你准确跟踪到底发生了什么的结果。此外,你正在做的事情也将在Tcl 8.6中失败,因为它也有NRE(非递归执行引擎)实现的命令,并且那些不以任何有用的方式使用objProc字段。我们正在考虑对未来版本的Tcl进行更大规模的修改(例如本机代码编译);你的拦截能力将进一步降低。

简而言之,你需要使用一种不同的方法,因为你要做的就是强烈反对现在运作良好的方法。例如,拦截由您控制的代码创建的所有过程或命令可能就足够了,而且开销会低得多。拦截过程的最简单方法是重写proc命令:

rename proc my_real_proc
my_real_proc proc {name arguments body} {
    set body "[list my_trace_hook $name];$body"
    uplevel 1 [list my_real_proc $name $arguments $body]
}

然后,您可以通过任何您想要的机制,在my_trace_hook中获取有关该过程的信息;它是从钩子程序内部调用的。它不会跟踪所有Tcl命令的作用,但添加该级别跟踪将始终对性能产生重大影响(仅将其添加到I / O命令中)。

如果不这样做,为什么要跟踪合奏本身呢?只需跟踪其中的子命令即可。 Tcl C API可以很容易地告诉您命令是否是一个集合,并提供其他内省选项。