0

我正在为我的程序使用 TCL-C API。
我阅读并创建了类似于这个C++ 示例的测试程序。
但我对这个例子有疑问。当我在 shell 中使用这个示例时(通过使用 load 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  

测试.tcl

package require ::somepackage 1.0
load somefile.o   # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...
4

1 回答 1

1

但我对这个例子有疑问。当我在 shell 中使用这个示例时(通过使用 load example.o 加载它),每个输入都会自动调用 API 的解释器并运行与输入字符串相关的命令。

如果您的脚本片段以准确的方式代表您的实际实现,那么问题是一旦您的扩展被编辑,您的 Tclproc命名doSomething就会被 C 实现的 Tcl 命令替换。load过程和命令位于相同的命名空间中。当加载顺序颠倒时,问题将保持不变。

我读到一切都由 tcl interperter 评估,所以在这种情况下,我应该以特殊方式命名 C 包装函数的 tcl 名称,例如 cFunc。但我不确定这一点。

这是对的。您必须以一种名称不会相互冲突的方式组织 C 实现的命令及其脚本包装器。一些(基本)选项:

  • 使用两个不同的 Tcl 命名空间,具有相同的命名过程
  • 将一些命名约定应用于包装过程和命令(您的cFunc提示)
  • 如果您的 API 作为实际的 Itcl 或 TclOO 对象提供,并且单独的命令是方法,您可以使用子类或 mixin 来托管细化(使用超级引用,例如next在 TclOO 中,从脚本细化转发到C 实现)。

当前设置中的热修复解决方案(最好由某些实际设计代替)将是 torenameinterp hide冲突命令:

  1. load somefile.o
  2. 隐藏现在可用的命令:interp hide {} doSomething
  3. 定义一个脚本包装器,在某个时候调用隐藏的原始包装器:

例如:

proc doSomething {args} {
  # argument checking
  set temp [interp invokehidden {} doSomething {*}$args]
  # result checking
  return $temp
}
于 2018-08-25T20:41:20.453 回答