我在我的应用程序中链接了一个更新的.lib文件,但是却使用了一个较旧的.dll文件。这样做可能会有哪些副作用?如果两个版本之间的函数原型相同,那么一切都应该正常工作,对吗?如果更新的版本更改了参数的默认值,那么该值是在.lib文件中还是.dll文件中?
- calling convention
- export name
- parameter list (including types)
A couple of definitions:
entry points are externally accessible functions or variables exported by the DLL. The interface is the set of all these exported functions and variables in a given version of the library. Regarding the libPNG version macros in makefile.cygwin:
You ONLY need to bump PNGDLL if the new dll REMOVES an entry point that the old dll provided. If you ADD a new entry point, then the new dll is a drop in replacement for the old one, since the new one provides everything the old one did.
Of course, an app compiled against the new version, which uses the additional entry points, won't work with the old dll -- but nobody ever promised FORWARD compatibility, only BACKWARD compatibility. This is the way cygwin DLL versioning works:
1) follow the libtool versioning scheme From 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
library implements. In other words, the library implements all the interface numbers in the range from number current - age to current.
Updating libtool versioning: 1. Start with version information of 0:0:0 for each libtool
library.
2. Update the version information only immediately before a
public release of your software. More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster.
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
release of your package will not be binary compatible with any other release.
2) On windows/cygwin, the DLLVER is 'c - a' (trust me, this is correct,
but it's easier to explain by example).
So, here's an example: the libtool version is 5:4:3, which indicates revision 4 of the implementation of interface 5, which happens to be backwards compatible with the three previous interface definitions. (ie. it is safe for applications linked against interfaces 5, 4, 3 and 2 to load the 5:4:3 dll at runtime).
So, let's look at the likely history of the mystery dll. I am following the c:r:a update rules described above.
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)
All of these DLLs with DLLVER = 2 (2:0:0, 3:0:1, 4:0:2, 5:0:3, 5:1:3, 5:2:3, 5:3:3, and 5:4:3) are all strictly backwards compatible: it is guaranteed that any newer DLL in the series can be loaded by an exe that was compiled against an older DLL in the series.
In 1.2.3, the DLLVER was 12. Let's pretend that was a 'c' - 'a' of 12, and that 'c' = 12 and 'a' = 0.
In [libpng] 1.2.4, you simply added some new functions -- but did NOT remove any. So, the new libtool number is 13:0:1 -- and DLLVER remains 12.
不要这样做。
我之前遇到过“新库,旧动态链接库”问题,它们真的很让人头疼。只有当每个公开可见类型具有完全相同的签名时,才算是“安全”的,这基本上意味着库作者必须把二进制兼容性作为优先考虑。否则,你最终会遇到奇怪的堆损坏错误,通常直到程序运行了一段时间才会显现出来。
回答你具体的问题:默认参数实际上是头文件的属性,而不是库的属性。
默认参数应该在.h文件中,所以这部分可能没问题。
否则,可能的结果是当.DLL没有按预期执行时很难找到错误。
只有在旧版本和新版本的dll之间保持了二进制兼容性时,这才是可行的。
简单来说,如果:
如果以上条件不满足,则很有可能会出现一些非常有趣的错误/崩溃/内存泄漏等。