Link 到同一个 DLL 两次 - 同时隐式和显式

Link to the same DLL twice - Implicit and explicit at the same time

我正在处理的项目加载同一个库两次:

  1. 使用 LoadLibrary
  2. 使用 lib 文件和“__declspec(dllimport/dllexport)”静态加载 DLL。

这种情况下发生了什么?这 2 "loadings" 是使用相同的堆还是共享其他东西。例如。它与两次调用 LoadLibrary 相同或相似吗?

我的一般问题是,当通过第二种方法从 exe 调用 dll 方法时,我遇到了堆栈损坏问题。而且我想知道问题是否可能是因为第一次加载?所有项目都使用相同的 RT、比对等。

By "statically loads the DLL with a lib file and _declspec(dllimport/dllexport)" 我假设您的意思是您使用 .lib 作为依赖项编译了可执行文件,并且在运行时 .dll 由 exe 自动加载(在开始时)。这是来自 FreeLibrary (surprisingly) MSDN page 的片段:

The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file.

换句话说,.dll 在应用程序启动时加载(因为您 link 反对它)并且 LoadLibrary just increments its ref count (). For more info you could also check DllMain, or this dll guide.

绝对没有理由在同一个应用程序中对同一个 .dll 使用这两种方法。

第二种方法是首选方法,if .dll 带有 .h 文件(保存库导出的函数定义,在编译时需要)和一个 .lib 文件(指示喜欢者添加来自 的引用。 dll 文件到可执行文件)。

另一方面,如果您只有 .dll 文件并且您以某种方式拥有它导出的函数的签名,那么第一种方法是唯一的方法。在这种情况下,您必须在应用程序中定义指向这些函数的指针并使用 GetProcAddress 初始化它们。在某些情况下,这种方法是首选,例如,当 .dll 中的功能仅在程序流的极端情况下需要时,在这种情况下,[=79 没有意义=] 反对 .lib 文件并在应用程序启动时加载 .dll 如果假设在 99% 的情况下不需要它.此外,这种方法的一个主要优点是:如果 .dll 以某种方式被删除,那么只有与其相关的功能将不起作用(LoadLibrary 将失败),而使用其他方法,应用程序将无法启动。

现在,如果没有详细信息,我无法深入了解您 运行 遇到的 这个 特定问题。你说你调用了一个函数 "normally" (根据它在 .h 文件中的定义),如果你使用函数指针调用它(使用相同的参数)它会失败它成功了吗?什么是堆栈错误消息?

注意:根据我的经验,在这种情况下堆栈损坏的典型原因是 callercalleestdcall vs cdecl 反之亦然)。混合使用 DebugRelease 也会带来问题。