【问题标题】:Writing a Tcl extension that will work with multiple versions of Tcl编写一个可以与多个版本的 Tcl 一起工作的 Tcl 扩展
【发布时间】:2013-04-24 20:42:15
【问题描述】:

在我的公司,我们目前使用的是 Tcl 8.4,我们希望更新到 8.6。我们想要做到这一点的方法是编写所有新的 C++ 扩展以与 8.6 和 8.4 兼容,以便所有新扩展都可以在我们由于兼容性问题而无法更新到 8.4 的旧测试仪上运行。

有没有办法编写代码或配置 VS 2012 以便 dll 检测 Tcl 的版本并动态加载它需要的库?

如果我使用茶壶扩展架构,我会得到相同的结果吗?

【问题讨论】:

  • 如果你使用 Stub 机制,这应该是没有必要的。
  • @JohannesKuhn 也许我没有正确实现存根。目前,我在“C++ 预处理器定义”下的 VS 项目设置中定义USE_TCL_STUBS,并在“链接器输入附加依赖项”下的 VS 项目设置中包含“tclstub84.lib”。有什么方法可以通过编程而不是通过项目设置来完成?
  • 您是否尝试使用 Tcl 8.6 load 您的 .dll(使用 8.4 构建)?
  • @JohannesKuhn 是的,我做到了,它确实在 8.4 到 8.6 之间工作。你知道有什么方法可以做相反的事情吗?只要您不使用 8.4 中不存在的任何方法,就将 8.6 中内置的库加载到 8.4 中。另外,顺便说一句,8.4 中内置的加载到 8.6 中的 .dll 在 8.5 中没有加载,对此有什么想法吗?
  • 完全不支持其他方向。针对您希望支持的最旧版本的 Tcl 构建支持存根的版本,然后您可以 load 进入更高版本。

标签: c++ dll visual-studio-2012 tcl compatibility


【解决方案1】:

我从 cmets 中看到,您已经知道如何构建使用存根机制的库。

存根机制的设计目的是让您可以使用 load 将 DLL 带入任何版本的 Tcl 中,即 ABI-与构建 DLL 的 Tcl 版本兼容。 Tcl 还具有A应用程序Binary I接口兼容性规则,这意味着更高版本具有相同的主要版本号(“8.4”中的“8”)与早期版本兼容。

反之则不然。 8.4 与 8.6 不兼容 ABI,或者至少我们不保证它是。即使撇开 8.6 中没有 8.5 或 8.4 的附加 API 函数这一事实,存根表中用于特定功能可能已经移动(自动生成的 C 宏管理前向 API 兼容性,但不应对反向兼容性)。您应该始终针对您希望支持的最旧版本的 Tcl API 和存根库构建您的扩展 DLL。 (我知道有几个人不这样做;他们的代码非常复杂,根本不推荐作为一种方法。)

但是……

这不是您可以采取的唯一方法。您还可以针对您希望支持的每个 Tcl 版本构建库,生成许多您指定不同名称的 DLL,可能是 mylib84.dllmylib85.dllmylib86.dll。然后,您将这些组合成一个 Tcl 包以及一个知道如何加载正确包的 pkgIndex.tcl,可能像这样:

if {[package vsatisfies [info tclversion] 8.6]} {
    package ifneeded MyLib 1.0 [list load [file join $dir mylib86.dll]]
} elseif {[package vsatisfies [info tclversion] 8.5]} {
    package ifneeded MyLib 1.0 [list load [file join $dir mylib85.dll]]
} elseif {[package vsatisfies [info tclversion] 8.4]} {
    package ifneeded MyLib 1.0 [list load [file join $dir mylib84.dll]]
}

使用此方案,您甚至可以使 8.5 和 8.4 的版本不启用存根(如果这对您的情况有意义的话)。唯一的缺点是您的构建过程现在更加复杂:您必须构建库的三个版本而不是一个。

通过将代码制作成一个包并隐藏该包中发生的事情的详细信息,您可以做非常复杂的事情。例如,这种机制的变体可用于构建支持多种架构的单个可再发行包;支持 32 位 Windows、64 位 Windows 和各种版本的 Linux 的单个下载,这样您就可以提供一组直接的指令,而无需大量依赖于平台的位?你可以用包来做,成本只是一些构建复杂性、一些带宽和一些磁盘空间......

【讨论】:

  • 这是人们在 cmets 中告诉您的内容的扩展版本,如果您在使用存根时遇到问题,还有一个可能的(如果不是非常愉快的)解决方法。
  • 这是一个非常有趣的答案,当您以这种方式打包它们时,它只会产生 1 个 .dll 还是我必须在构建后维护多个 .dll 文件?
  • 您仍然有多个 DLL,但您会将它们放在同一个位置(名称略有不同),因此在构建后管理它们不会太难。然后,您可以将它们全部打包到一个 Starkit 中,这将由 ActiveTcl 支持,并且将是一个单文件解决方案。好吧,单文件一次构建(将包含多个 DLL,但无论如何)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多