【问题标题】:Loading tcl extension from tclsh从 tclsh 加载 tcl 扩展
【发布时间】:2015-03-06 15:22:15
【问题描述】:

我有一个 Tcl 的 C 扩展,其中定义了命令 mytest。扩展名编译正确(我在 Linux 上,扩展名是 *.so)。例如,我可以启动 tclsh 并像这样使用它:

$ tclsh
% load /path/extension.so
% mytest abc
...

但是,如果我创建一个包含以下内容的文件 myscript.tcl:

load /path/extension.so
mytest abc

然后我得到错误:

$ tclsh myscript.tcl 
invalid command name "mytest"
    while executing
"mytest abc"
    (file "myscript.tcl" line 2)

我在 Ubuntu 14.04 上使用 bash。 Tcl 8.6。

编辑 1:我的问题/问题是我想将 tclsh 与脚本一起用作参数 - 此脚本应正确加载扩展,以使 mytest 和其他已实现的函数正常工作。

编辑 2:嗯,如果我在 tcl shell 中使用命令“source myscript.tcl”,结果是一样的。如果我为 myscript.tcl 使用绝对路径,错误仍然相同 --- “加载”会在没有警告的情况下执行,但我不确定,因为我得到 invalid command name “mytest”。可能问题出在作用域上,但是当交互式使用 tclsh 时它可以正常工作。

【问题讨论】:

  • 问题到底是什么?
  • 在 tcl shell 中获取文件时会发生什么?

标签: tcl tclsh


【解决方案1】:

如果您在这两种情况下都使用扩展库的完整路径,则该部分的工作方式应该相同。它可能正在这样做;如果它无法加载它,它会产生一个错误(这可能会或可能不会有帮助,因为某些事情失败的方式提供的信息很少;Tcl 报告它已经得到了什么,但这有时还不够,因为它取决于操作系统来告诉它一些事情)。相反,问题可能出在其他地方。

交互使用和脚本使用之间的主要区别在于,在交互使用中,unknown 命令会将未知的命令名称扩展为您键入的内容是 unambiguous 前缀的 Tcl 命令。这很方便,但是在转换为脚本时,您应该始终使用完整的命令名称。好的,不是 full 完整的命令名称——你通常不想要或不需要前面的 :: 命名空间——但没有缩写,所以不要使用 lappe 代替 lappend。 (在交互式使用中,Tcl 还将 exec 事物作为外部程序,而不需要您显式键入 exec;同样,它在脚本中被关闭,因为它相当脆弱。)

难道这就是正在发生的事情?在输入代码之前,您可以通过将全局变量 tcl_interactive 设置为 0 来检查(我建议使用 cut-n-paste 进行输入,以便您确切地知道发生了什么) .如果失败了,那就是交互模式的帮助让你失望了。检查您可能有哪些命令作为前缀为 info commands 的扩展(当然是在 load 之后):

info commands mytest*

如果只是报告mytest,我的理论是错误的。 (好吧,如果它这样做并且该字符串的长度为 6;理论上可能在命令名称上放置了额外的不可见字符,这将是合法的 Tcl,但 非常 讨厌和 不要那样做!

【讨论】:

  • 谢谢。我知道脚本中的缩写,例如“put”和“puts”都可以交互工作,但脚本中只能使用“puts”。但是,如果我在“加载”之前使用“设置 tcl_interactive 0”,则新命令不可用。我有截图,我应该发布它吗?
  • 哦,我刚刚发现,确实,我对缩写有疑问。命令 mytest 实际上是 mytestPkg...问题解决了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多