潜在 DLL 兼容性问题的摘要?

summary of potential dll compatibility issues?

本文关键字:问题 DLL 兼容性 潜在      更新时间:2023-10-16

当(非托管)Win32程序(或其他DLL)调用(非托管)Win32 DLL时,我的理解是存在许多可能导致问题/崩溃的潜在不兼容性。

例如,如果程序P调用DLL D,并且P是用Visual Studio 2013编译的,目的是针对Windows SDK版本8,而D是用Visual Studio 2017编译成目标Windows SDK版本10的,我的理解是他们将访问不同的msvc运行时DLL,这可能会导致问题。例如,如果 D 使用new分配内存并将其传递回 P,并且 P 尝试delete它,则会出现崩溃,因为 P 和 D 使用两个不同的运行时,每个运行时都维护自己的堆。

同样,如果 P 是使用运行时类型信息 (RTTI) 构建的,而 D 不是,我的理解是,当 P 分配一个类实例(到每个类实例在公共 .h 文件中引用的类型)并将其传递给 D 时,可能会出现崩溃的不兼容性,因为虚函数表和/或结构字段之间的填充存在差异。

我试图了解可能存在哪些其他不兼容性。理想情况下,我想找到一个完整的列表。以下是我想到的一些可能性:

  • 结构杆件对齐(类似于 RTTI 问题)

  • 使用多字节字符集与使用 Unicode 字符集(如果传递/返回字符串对象可能会导致问题?

  • 省略(
  • 与不省略)帧指针(或者这可能适用,因为跨程序/DLL 的函数调用机制与此标志相关的内部函数调用机制不同?

  • 启用(或禁用)C++异常(如果异常处理都是在启用异常的情况下构建的并且使用相同的运行时,则它们在 DLL 调用中起作用?

  • 别人?

编辑

我问这个问题是出于普遍的好奇心,但也因为我在程序中使用 DLL 存在随机堆损坏,并且我试图找出可能的问题所在。

我的问题是我链接到过时的DLL导入库。我不确定为什么程序启动没有错误,以及为什么它基本上运行正常但间歇性堆损坏。我相信只有当新 DLL 提供旧 DLL 导入库提供的功能的超集时,它才能启动而不会出错。然后我不确定该机制是 C/C++ 运行时库中的不匹配,还是函数参数的更改而没有函数签名的重大更改?

无论如何,我想可以向列表中添加针对过时的DLL导入库的链接,尽管这是一个比提到的其他错误更无辜的错误。

一个非常常见的错误是在 dll接口中使用标准库的东西或其他编译器实现/版本相关的功能。 这通常仅在双方(dll 及其用户)使用相同的编译器版本时才有效,即使这样,当其中一个在启用 DEBUG 的情况下构建而另一个使用 NDEBUG 构建时,也可能存在不兼容。

仅在 dll 接口中使用 c 兼容类型等。