链接到不同版本的.dll的 .lib 可能有哪些副作用
What are possible side-effects of linking against a .lib that is a different version of the .dll?
我正在链接到较新的.lib,但在我的应用程序中使用较旧的.dll。这样做可能有什么副作用? 如果两个版本之间的函数原型相同,难道不应该一切正常吗? 如果较新版本更改了参数的默认值怎么办? 该值是在 .lib 中还是在.dll中?
是在调用站点编译的 - 因此 DLL 或 .lib 文件与此无关 - 更改标头将具有效果,而无需更改 ABI。
如果导出函数中的 ABI 没有更改,只要程序不使用新 .lib 中但不在新 DLL 中的新导出,您应该能够使用较旧的 DLL 和链接到较新的 .lib 的程序。
影响 ABI 的事情(我并不是说这是一个全面的列表):
- calling convention
- export name
- parameter list (including types)
"libtool 版本控制系统"(http://www.gnu.org/s/libtool/manual/libtool.html#Versioning)是一种用于识别共享库兼容性的技术。
请注意,如果您不使用 C 调用约定(即,导出名称将被"C++破坏"),那么从技术上讲,您几乎无法控制要导出的名称。
下面解释了某些Windows库(cygwin,pngdll)如何使用遵循libtool库版本控制技术的命名约定来管理向后兼容性。 这是来自 http://home.att.net/~perlspinr/libversioning.html 的网络档案 - 我在这里镜像它:
几个定义:
入口点位于外部 可访问的函数或变量 由 DLL 导出。界面是 所有这些导出的集合 给定中的函数和变量 库的版本。关于 libPNG 版本宏在 makefile.cygwin:
你只需要在以下情况下碰撞PNGDLL。 新 DLL 删除一个入口点 提供的旧 DLL。如果您添加新的 入口点,则新的 DLL 是一个 替换旧的, 因为新的提供了一切 旧的做到了。
当然,针对 新版本,它使用额外的 入口点,不适用于旧的 dll - 但没有人承诺过 向前兼容,仅向后兼容 兼容性。这就是西格温的方式 DLL 版本控制工作:
1) 遵循库工具版本控制 方案从 http://www.gnu.org/software/libtool/manual.html#Versioning:
So, libtool library versions are described by three integers: current The most recent interface number that this library implements. revision The implementation number of the current interface. age The difference between the newest and oldest interfaces that this
库实现。换句话说, 库实现所有 接口编号范围为 当前数字 - 年龄到当前。
Updating libtool versioning: 1. Start with version information of 0:0:0 for each libtool
图书馆。
2. Update the version information only immediately before a
公共 发布您的软件。不需要更频繁的更新, 和 只保证当前接口号变大 更快。
3. If the library source code has changed at all since the last update, then increment revision (c:r:a becomes c:r+1:a). 4. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. 5. If any interfaces have been added since the last public release, then increment age. 6. If any interfaces have been removed since the last public release, then set age to 0. Never try to set the interface numbers so that they correspond to the release number of your package. This is an abuse that only fosters misunderstanding of the purpose of library versions. Instead, use the -release flag (see Release numbers), but be warned that every
的发布 您的软件包将与任何其他版本不兼容。
2) On windows/cygwin, the DLLVER is 'c - a' (trust me, this is correct,
但更容易解释 示例)。
所以,这里有一个例子:libtool 版本为 5:4:3,表示 《公约》执行情况第4修订版 接口 5,恰好是 向后兼容三者 以前的接口定义。(即。 对于链接的应用程序是安全的 针对接口 5、4、3 和 2 至 在运行时加载 5:4:3 DLL)。
那么,让我们看看可能的历史 的神秘dll。我正在关注 c:r:A 上述更新规则。
oldest: interface definition 0, initial release: 0:0:0 (DLLVER = 0) removed an entry point: 1:0:0 (DLLVER = 1) NOT backwards compatible! but DLLVER does the right thing. source code changed, but no added or removed entry points: 1:1:0 (DLLVER = 1) more source code changes: 1:2:0 (DLLVER = 1) In all of the previous three releases, 'c' - 'a' = DLLVER = 1. removed an entry point (or renamed it): 2:0:0 (DLLVER = 2) This is INCOMPATIBLE. (But look: 'c' - 'a' = 2, so the DLLVER does the right thing) added a new function: 3:0:1 (DLLVER = 2) (this is BACKWARDS but not FORWARDS compatible. However, the DLLVER 'c' - 'a' still is 2, so that is good.) add eight more exported functions all at once 4:0:2 (DLLVER = 2) add another function: 5:0:3 (DLLVER = 2) source code changes, but no new interfaces: 5:1:3 (DLLVER = 2) again: 5:2:3 (DLLVER = 2) again: 5:3:3 (DLLVER = 2) again: 5:4:3 (DLLVER = 2)
所有这些 DLL 与 DLLVER = 2 (2:0:0, 3:0:1, 4:0:2, 5:0:3, 5:1:3, 5:2:3、5:3:3 和 5:4:3) 都是 严格向后兼容:它是 保证任何较新的 DLL 在 系列可以由 exe 加载 是针对较旧的 DLL 编译的 该系列。
在 1.2.3 中,DLLVER 是 12。让我们 假装是 12 的"c"-"a", 并且"c"= 12,"a"= 0。
在 [libpng] 1.2.4 中,您只需添加 一些新功能 - 但没有 删除任何。所以,新的库工具编号 是 13:0:1 -- DLLVER 仍然是 12。
这样做。
我以前处理过"新 LIB,旧 DLL"问题,诊断起来真的非常烦人。只有当每个公开可见的类型都具有完全相同的签名时,它才是"安全的",这基本上意味着库作者必须优先考虑二进制兼容性。否则,您最终会遇到奇怪的堆损坏错误,这些错误通常直到程序运行一段时间后才会显现出来。
要回答您的具体问题:默认参数实际上是头文件的属性,而不是库的属性。
默认参数应该在 .h 文件中,所以这部分可能没问题。
否则,当.DLL没有按预期执行时,可能的结果通常是很难找到错误。
且仅当旧版本的 dll 之间保持二进制兼容性时,这才没问题。
简单来说。如果:
- 工具使用的 DLL 头文件没有更改,并且
- 没有添加或删除导出的符号,您可能没问题。
如果不满足这些条件中的任何一个,您很有可能会遇到一些非常有趣的错误/崩溃/内存涂鸦等。
- 有没有可能有一个只有ADL才能找到的非好友功能
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- Winsock2 select():同一个套接字上可能有多个事件吗?
- strncmp 有副作用吗?
- 是否有可能有一个派生类继承最终函数但创建相同的函数(而不是重写)
- 打印所有可能有 4 个字母的单词的时间太多
- 使用 gcc 的 -fno-math-errno 可能有什么副作用?
- 长镜头 -- 可能有一个静态类成员,该类成员具有访问非静态成员的 lambda
- 画线不起作用,可能有什么问题?
- 嵌入式串行读取操作和桌面PC之间可能有什么区别
- 如何/是否有可能有一个载体<unique_ptr<ABC>>?
- 斯特伦有副作用吗
- 怎么可能有两个同名的变量——一个是全局变量,另一个是局部变量
- 是否有可能有一个程序将键盘输入更改为所有其他程序
- 是否有可能有一个指针指向由奇怪的递归模板创建的基类
- VS 2012 中可能有什么变化来破坏我的C++应用程序?
- LNK2005错误,已定义:可能有一个定义规则违反
- 是否可能/有必要在单独的线程[MFC]中调用OnDraw
- [[noreturn]]函数怎么可能有返回类型
- 链接到不同版本的.dll的 .lib 可能有哪些副作用