【问题标题】:Can changes to a dll be made, while keeping compatibility with pre-compiled executables?是否可以对 dll 进行更改,同时保持与预编译的可执行文件的兼容性?
【发布时间】:2011-09-30 19:09:38
【问题描述】:

我们有很多引用我们的 dll 的可执行文件。我们在我们的一个 dll 中发现了一个错误,并且不想重新编译和重新分发我们所有的可执行文件来修复它。 我的理解是,只要您不更改头文件中的任何内容,dll 就会保持与其可执行文件的兼容性。所以没有新的类成员,没有新的函数,等等......但是对函数中的逻辑进行更改应该没问题。它是否正确?如果它是特定于编译器的,请告诉我,因为这可能是个问题。

【问题讨论】:

    标签: c++ windows dll backwards-compatibility


    【解决方案1】:

    你的理解是正确的。只要你改变逻辑而不是接口,那么你就不会遇到兼容性问题。

    您必须小心的是,DLL 的接口是否不仅仅是函数签名。例如,如果原始 DLL 接受 int 参数,但新 DLL 强制执行此参数的值必须为正的约束,例如,您将破坏旧程序。

    【讨论】:

    • +1。反之亦然,这有点棘手。如果返回类型是int,旧的DLL 总是返回一个正值,而EXE 的一个预期是这样的,新的DLL 不能返回一个负值。 (更难,因为您必须检查所有 EXE 的假设,而不仅仅是旧的 DLL。)这些约束通常称为前置条件和后置条件。
    【解决方案2】:

    这会奏效。只要 DLL 的接口保持不变,旧的可执行文件就可以加载并正常使用它。话虽如此,您正踏上一条非常危险的道路。随着时间的推移,您修补越来越多的 DLL,您可能会开始在客户安装中看到几乎无法诊断的奇怪行为。这是由于各种组件的不同版本之间的意外交互引起的。从历史上看,这个问题被称为 DLL 地狱。

    在我看来,重建、重新测试和重新分发整个应用程序是一个更好的主意。我什至会更进一步,建议您使用应用程序清单来确保您的可执行文件可以与特定版本的 DLL 一起使用。现在看起来工作量很大,但它确实可以为您在未来省去很多麻烦。

    【讨论】:

    • 我们每隔几个月左右就重建和发布我们软件的新版本。所以这实际上只是一个临时修复,直到我们的下一个完整版本,所以我认为在这种情况下我们可以避免 dll 地狱。在用户系统上替换 1 个 dll 比替换所有内容要容易得多。
    【解决方案3】:

    视情况而定

    理论上是的,如果您使用 LoadLibrary 加载 dll 并且没有更改界面,您应该没问题。

    如果您使用某些 .lib 存根与 .dll 文件进行 OTOH 链接,则无法保证它会起作用。

    这就是发明 COM 的原因之一。

    【讨论】:

    • 只要 DLL 接口没有改变,使用 .lib 存根就完全没有问题。发明 COM 的原因完全不同。
    猜你喜欢
    • 2014-03-21
    • 2012-03-15
    • 1970-01-01
    • 2018-10-13
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多