c++ - 编写可与多个版本的 Tcl 一起使用的 Tcl 扩展

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

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

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

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

最佳答案

我从评论中看到您已经知道如何构建使用 stub 机制的库。

stubs 机制被设计成这样工作,你可以使用 load 将 DLL 引入任何版本的 Tcl,即 ABI 与构建 DLL 所针对的 Tcl 版本兼容。 Tcl 还具有A应用B二进制I接口(interface)兼容性规则,这意味着具有相同以后版本主要版本号(“8.4”中的“8”)与早期版本兼容。

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

但是……

这不是您可以采用的唯一方法。您还可以针对您希望支持的每个 Tcl 版本构建库,生成许多您指定不同名称的 DLL,例如 mylib84.dllmylib85.dllmylib86.dll。然后,将它们与知道如何加载正确的 pkgIndex.tcl 一起组合到一个 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 的版本不启用 stub (如果这对您的情况有意义)。唯一的缺点是您的构建过程现在更加复杂:您必须构建三个版本的库,而不是一个。

通过将代码放入一个包中并隐藏该包中正在发生的事情的细节,您可以做非常复杂的事情。例如,此机制的变体可用于构建支持多种体系结构的单个可再分发包;支持 32 位 Windows、64 位 Windows 和各种版本的 Linux 的单个下载,以便您可以提供一组直接的指令,而无需大量平台相关位?你可以用包来做,成本只是一些构建复杂性、一些带宽和一些磁盘空间……

关于c++ - 编写可与多个版本的 Tcl 一起使用的 Tcl 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16201783/

相关文章:

c++ - C++ 中的大量问题

c++ - 使用clog计算复数的自然对数时,如何解决出现的歧义?

c# - Visual Studio 查看 DLL 中的 StandardOuptut 流

c# - 如何停止“在关闭解决方案之前必须停止构建”

visual-c++ - 为什么以下代码不会覆盖 C++ CLI 中的基类属性?

c++ - 为什么不允许将类成员定义的 `static` 关键字放在命名空间范围内?

c++ - 减少斐波那契堆中的操作, boost

c++ - 将 Delphi 类传递给需要具有 __thiscall 方法的类的 C++ 函数/方法

c++ - 在 C++ 中导入 DLL 并使用 extern 函数

c++ - 使用 OpenCV 2.4.3 的双线性插值的 VideoCapture 旋转