C++ 单元测试项目 LoadLibrary 失败并出现 Ordinal Not Found 错误

标签 c++ unit-testing mfc loadlibrary

我有一个 C++ 单元测试项目,我正在使用 LoadLibraryEx 函数加载我为我的应用程序创建的 dll,但是 LoadLibraryEx 失败并返回 NULL 之后我调用了 GetLastError 函数,错误为 182。我还注意到在执行 LoadLibraryEx 行后的输出窗口中出现错误 Exception thrown at 0x771718D6 vstest.executionengine.x86.exe 中的 (ntdll.dll):0xC0000138:未找到序号。

请注意,当我运行应用程序时,库加载成功,加载仅在从单元测试加载时失败。

最佳答案

你的 dll 是 import TaskDialogIndirect 来自 Comctl32.dll 的函数。但此函数仅由 Comctl32.dll版本 6 和更高版本导出。但要使用此版本,必须是存在的事件激活上下文:

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' 
        name='Microsoft.Windows.Common-Controls' 
        version='6.0.0.0' processorArchitecture='*'   
        publicKeyToken='6595b64144ccf1df' />
    </dependentAssembly>
  </dependency>

否则会加载5.82 version ComCtl32.dll 不导出 TaskDialogIndirect和 dll 加载失败。

哪个激活上下文将在 dll 加载时激活?

如果 dll 有自己的 list (RT_MANIFESTISOLATIONAWARE_MANIFEST_RESOURCE_ID)- 将根据 dll list 创建激活上下文,并将在 dll 加载期间使用它。否则它是未定义的。这可以是(最快速的)基于来自 exe 文件或其他文件的 list 创建的上下文。

根据您的错误-我可以说-您的 dll 没有(RT_MANIFESTISOLATIONAWARE_MANIFEST_RESOURCE_ID) list 资源。这是错误。加载您的 dll 的应用程序可能有自己的 list ,其中声明了通用控件的版本 6,因此 dll 加载正常。但是单元测试 exe 根本没有 list ,或者 list 中没有版本 6。结果加载了旧版本的 comctl32.dll 并且此处未导出 TaskDialogIndirect .

无论如何,dll 不能依赖于外部上下文 - 它加载的地方。为此,它必须有自己的 list 。

因此为 dll 创建 list ,其中有 <dependency> - <dependentAssembly>对于 <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' />并将此 list 作为资源包括在内:

ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest file name"

有了这个,当你的 dll 将被加载时 - 总是使用版本 6+ 的 comctl32.dll


如何研究这样的错误?

最有效的方式集DWORD LdrpDebugFlagsntdll.dll (在 xp 中 - BOOLEAN ShowSnapstrue )到 0xFFFFFFBF就在调用 LoadLibrary 之前在调试器中。作为结果,链接器在 dll 加载期间打印详细的调试消息 - 您可以准确查看进程失败的位置。此外,在某些困难的情况下,也最好记录成功的 dll 加载并比较此日志。

the ordinal 345 could not be located in the dynamic link library comctl32.dll

当我们有序号而不是名称时 - 运行

link.exe /dump /exports "<path>comctl32.lib" > comctl32.log

然后查看日志。在日志中我们可以发现:

345    TaskDialogIndirect

现在查看 TaskDialogIndirect 的 msdn 要求部分- 当我们查看 Comctl32.dll(版本 6)时 - 一切都变得清晰

关于C++ 单元测试项目 LoadLibrary 失败并出现 Ordinal Not Found 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48491014/

相关文章:

unit-testing - 在 Go 中模拟接收函数

c++ - MFC:如何创建带有列表框和多页的选项对话框?

windows - BOOL 和 bool 有什么区别?

c++ - 关于 C++ 中的右移运算符 >>

c++ - 在 c++20 中删除了默认构造函数的聚合初始化

java - 使用 Mockito 2 模拟最后一个类

c++ - 如果 CHttpConnection::OpenRequest 返回 NULL 我如何找出原因

c++ - 防止默认点击事件 (WinAPI)

C++ MFC double 到 CString

node.js - 在 Karma 的运行器中包含 Jasmine Node 文件