调用 TCL C API 的内部 tcl 包过程
invoking TCL C API's inside tcl package procedures
我正在为我的程序使用 TCL-C API。
我阅读并创建了与此类似的测试程序 C++ example。
但是我对这个例子有疑问。当我在 shell 中使用此示例时(通过加载 example.o),每个输入都会自动调用 API 和 运行 相关命令的解释器输入字符串。
但是假设我希望输入将调用我需要的包内的 tcl 过程,这个过程将检查参数并打印另一条消息,只有在这之后才会调用 TCL-C API 相关函数(种类的包装),在这种情况下我该怎么做?
我在某处读到符号 @
是应该用于调用外部程序的符号,但我找不到它在哪里。
我将举一个小例子来使事情更清楚。
somepackage.tcl
proc dosomething { arg1 , arg2 , arg3 } {
# check args here #
set temp [ #invoke here TCL-C API function and set it's result in temp ]
return $temp
}
package provide ::somepackage 1.0
test.tcl
package require ::somepackage 1.0
load somefile.o # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...
But I have a problem with this example. when I use this example in the
shell (by loading it with load example.o) every input automatically
invokes the interpreter of the API and run the command that is related
to the input string.
假设您的脚本片段以准确的方式代表了您的实际实现,那么问题是一旦您的扩展被替换,您名为 doSomething
的 Tcl proc
将被 C 实现的 Tcl 命令替换load
编辑。过程和命令位于相同的名称空间中。当加载顺序颠倒时,问题仍然存在。
I read that everything is being evaluated by the tcl interperter so in
this case I should name the tcl name of the C wrap functions in
special way for example cFunc. But I am not sure about this.
这是正确的。您必须以一种名称不相互冲突的方式组织 C 语言实现的命令及其脚本化包装器。一些(基本)选项:
- 使用两个不同的 Tcl 名称空间,具有相同的命名过程
- 对包装过程和命令应用一些命名约定(您的
cFunc
提示)
- 如果您的 API 是作为实际的 Itcl 或 TclOO 对象提供的,并且各个命令是方法,您可以使用子类或混入来托管改进(使用超级引用,例如
next
在 TclOO 中,从脚本优化转发到 C 实现)。
您当前设置中的热修复解决方案(最好用一些实际设计代替)是 rename
或 interp hide
冲突命令:
load somefile.o
- 隐藏现在可用的命令:
interp hide {} doSomething
- 定义一个脚本包装器,在某个时候调用隐藏的原始文件:
例如:
proc doSomething {args} {
# argument checking
set temp [interp invokehidden {} doSomething {*}$args]
# result checking
return $temp
}
我正在为我的程序使用 TCL-C API。
我阅读并创建了与此类似的测试程序 C++ example。
但是我对这个例子有疑问。当我在 shell 中使用此示例时(通过加载 example.o),每个输入都会自动调用 API 和 运行 相关命令的解释器输入字符串。
但是假设我希望输入将调用我需要的包内的 tcl 过程,这个过程将检查参数并打印另一条消息,只有在这之后才会调用 TCL-C API 相关函数(种类的包装),在这种情况下我该怎么做?
我在某处读到符号 @
是应该用于调用外部程序的符号,但我找不到它在哪里。
我将举一个小例子来使事情更清楚。
somepackage.tcl
proc dosomething { arg1 , arg2 , arg3 } {
# check args here #
set temp [ #invoke here TCL-C API function and set it's result in temp ]
return $temp
}
package provide ::somepackage 1.0
test.tcl
package require ::somepackage 1.0
load somefile.o # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...
But I have a problem with this example. when I use this example in the shell (by loading it with load example.o) every input automatically invokes the interpreter of the API and run the command that is related to the input string.
假设您的脚本片段以准确的方式代表了您的实际实现,那么问题是一旦您的扩展被替换,您名为 doSomething
的 Tcl proc
将被 C 实现的 Tcl 命令替换load
编辑。过程和命令位于相同的名称空间中。当加载顺序颠倒时,问题仍然存在。
I read that everything is being evaluated by the tcl interperter so in this case I should name the tcl name of the C wrap functions in special way for example cFunc. But I am not sure about this.
这是正确的。您必须以一种名称不相互冲突的方式组织 C 语言实现的命令及其脚本化包装器。一些(基本)选项:
- 使用两个不同的 Tcl 名称空间,具有相同的命名过程
- 对包装过程和命令应用一些命名约定(您的
cFunc
提示) - 如果您的 API 是作为实际的 Itcl 或 TclOO 对象提供的,并且各个命令是方法,您可以使用子类或混入来托管改进(使用超级引用,例如
next
在 TclOO 中,从脚本优化转发到 C 实现)。
您当前设置中的热修复解决方案(最好用一些实际设计代替)是 rename
或 interp hide
冲突命令:
load somefile.o
- 隐藏现在可用的命令:
interp hide {} doSomething
- 定义一个脚本包装器,在某个时候调用隐藏的原始文件:
例如:
proc doSomething {args} {
# argument checking
set temp [interp invokehidden {} doSomething {*}$args]
# result checking
return $temp
}