2016-09-27 46 views
0

我需要在每個在tcl解釋器中註冊的命令之前調用一個代理函數(C/C++)。對於隨便的命令來說很簡單,我得到Tcl_CmdInfo,記住它,並用我的代理功能將設置爲objProc字段。當我的代理被調用,然後我做我需要的,然後我從原始Tcl_CmdInfo調用objProc。它工作正常。如何爲'ensemble'命令創建C/C++代理

問題是,當我爲他們調用Tcl_SetCommandInfo時,合奏命令(info,dict等)停止爲「合奏」。它們工作正常,但不能再被「命名空間集成」修改。有任何想法嗎?

PS。追蹤不是這裏的解決方案:它慢了幾倍,我不能接受它。

回答

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可以很容易地告訴你一個命令是否是一個集合,並提供其他自省選項。

+0

我沒有考慮跟蹤子命令,我會試試看,謝謝! – Bogdan