从插件调用时LoadLibrary()失败,但可以在测试程序中使用

时间:2019-05-20 12:01:42

标签: c++ winapi dll 3dsmax

我正在使用plugin for Autodesk 3ds Max2017。根据Max's documentation,该插件是在VS 2017内部使用VS 2015工具集针对10.0.10586.0 Windows SDK进行编译的。

当插件由3ds Max加载时,它依次使用LoadLibrary()以编程方式加载许多DLL。直到最近,这在我的机器上仍能正常工作。在其他开发人员的计算机上,它仍然可以正常工作。

我的计算机上现在发生的情况是LoadLibrary()失败并返回空句柄。错误代码为127,即“找不到指定的过程。”

我非常确定我要加载的DLL依赖于系统上。我已经对Dependency Walker及其现代化身Dependencies进行了三重检查。

实际上,在Visual Studio 2017中运行以下程序(也针对10.0.10586.0 Windows SDK使用VS 2015工具集)能够很好地加载该DLL:

#include <Windows.h>

int main(int argc, char* argv[])
{
    auto result = LoadLibrary(L"C:\\path\\to\\appleseed.dll");
}

为了进一步研究此问题,我转到了GFlags,它是Windows 10调试工具的一部分。

这是调用LoadLibrary() https://gist.github.com/dictoon/b3f9f7cb52d2d81078965133d5035a03

时发出的完整调试器输出

我相信(但我不是100%肯定)此输出的相关错误如下:

5f4c:54bc @ 131346281 - LdrpReportError - ERROR: Locating export "StackWalkEx" for DLL "C:\Windows\SYSTEM32\dbgeng.dll" failed with status: 0xc0000139.
Exception thrown at 0x00007FFCC6A9EAA8 (ntdll.dll) in 3dsmax.exe: 0xC0000139: Entry Point Not Found.
5f4c:54bc @ 131346281 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapModule raised exception 0xc0000139
    Exception record: .exr 000000000223F030
    Context record: .cxr 000000000223EB40

dbgeng.dll似乎是Visual Studio的调试器,所以我认为也许只有在3ds Max在附有调试器的Visual Studio中运行时才会发生错误,但事实并非如此:当3ds加载DLL时也无法加载Max会自行启动。

检查C:\Windows\SYSTEM32\dbgeng.dll的依赖关系表明它确实导出了StackWalkEx()符号

编辑1 :@RbMm评论说StackWalkEx()实际上不是由dbgeng.dll而是由dbghelp.dll导出的,如下图所示:

Dependencies screenshot showing that dbgeng.dll does export StackWalkEx

编辑2 :在我尝试加载的DLL的发行版中,一切正常。查看调试器的输出,未尝试加载dbgeng.dll或找到StackWalkEx()

编辑3 :似乎我要加载的库的调试版本 dbgeng.dll有依赖性:

Library that fails to load depends on dbgeng.dll

但是从头编写的小型测试DLL却没有!

编辑4 :我现在怀疑(最近从Boost 1.55切换到的)Boost 1.69(我要加载的DLL依赖于它)引入了对{{1 }}通过Boost 1.65中引入的Stacktrace库。

1 个答案:

答案 0 :(得分:1)

问题是dbghelp.dll的较旧版本与3ds Max一起提供,并且与在调试构建过程中链接到appleseed.dll的较新版本冲突。

对函数StackWalkEx的调用失败了,它依赖于dbghelp.dll StackWalkEx function

解决方案是停用或替换Max根目录中的dbghelp.dll的较旧的,不兼容的版本。

StackWalkEx是DbgHelp的一部分,由系统服务使用。它可能是Windows更新过程中最近更新的版本,已引起重大更改。