加载库失败; GetLastError 没有帮助
我有一个从 Visual Studio 2003 .NET 转换为 Visual Studio 2010 的项目。它不是 .NET 项目;它是一个项目。它是 Visual C++(非托管)。
该 DLL 会引入其他 DLL。如果我将一个可执行文件与该 DLL 链接,则该可执行文件会在 DLL 初始化期间终止。 (我可以看出,有正在调用的静态对象的构造函数,并且我可以看到它们的操作。)我已经从我的路径中删除了所有 VS 2010 创建的 DLL,除了其中一个,这会导致错误。将其替换为 VS.NET 创建的版本即可允许程序运行。
由于我没有获得任何有用的信息,因此我决定编写一个不直接链接到 DLL 的测试应用程序,而是使用 LoadLibrary 来加载库。我的想法是我可以使用 GetLastError() 来帮助解决库的问题。不许走;我收到错误代码 -529697949,这根本不是 Windows 错误代码! (如果我将 DLL 更改为 VS.NET 创建的版本,程序会正确加载 DLL。)
我使用 Dependency Walker (www.dependencywalker.com) 检查 DLL,它告诉我“至少有一个延迟” -未找到加载依赖模块”,突出显示 IESHIMS.DLL 和 WER.DLL。我没有看到该工具有其他错误。在 VS.NET 创建的 DLL 上运行它会显示相同的两个警告,所以我认为这是一个转移注意力的事情。
static void showMessage(const wchar_t *wmsg)
{
std::wcout << wmsg << std::endl;
::MessageBox(NULL, wmsg, TEXT("Message"), MB_OK);
}
static void testLoadLibrary(const wchar_t *lib)
{
::SetLastError(0L);
::SetErrorMode(0);
std::wstringstream wss;
wss << "LoadLibrary: " << lib;
showMessage(wss.str().c_str());
HINSTANCE LoadME = ::AfxLoadLibrary(lib);
if (LoadME == NULL) {
DWORD dw = ::GetLastError();
wss << "Failed: Error code " << dw;
showMessage(wss.str().c_str());
ErrorExit(lib, dw);
} else {
wss << "LoadLibrary of " << lib << " succeeded.";
showMessage(wss.str().c_str());
::FreeLibrary(LoadME);
}
}
最后,我运行 Process Monitor (sysinternals.com) 来监视测试程序,查看 Path 包含字符串“dll”的所有条目。我在这个列表中没有看到任何特别有用的信息——不知道为什么 DLL 无法加载。
如果我将 LoadLibraryEx 与 DONT_RESOLVE_DLL_REFERENCES 一起使用,则会加载库,因此这看起来确实像是一个依赖项问题,这就是为什么我对依赖项遍历器没有特别帮助感到惊讶的原因。
我已经在 Windows 2008 R2 和 Windows 2003 上尝试过了;相同的行为。
有什么建议吗?
I have a project that I converted from Visual Studio 2003 .NET to Visual Studio 2010. It's NOT a .NET project; it's Visual C++ (unmanaged).
The DLL pulls in additional DLLs. If I link an executable with this DLL, then the executable dies during the initialization of the DLL. (I can tell, there are constructors for static objects that are being called, and I can see their operation.) I've removed ALL VS 2010-created DLLs from my path, except for one of them, which causes the error. Replacing that one with the VS.NET-created version allows the program to run.
Since I'm not getting any useful information, I decided to write a test application that doesn't directly link to the DLL, but instead uses LoadLibrary to load the library. The idea was that I could use GetLastError() to help figure the issue with the library. No go; I get an error code -529697949, which isn't a Windows error code at all! (If I change the DLL to the VS.NET-created version, the program loads the DLL properly.)
I used the Dependency Walker (www.dependencywalker.com) to check the DLL, and it tells me that "At least one delay-load dependency module was not found," highlighting IESHIMS.DLL and WER.DLL. I am seeing no other error with that tool. Running it on the VS.NET-created DLL shows the same two warnings, so I figure this is a red herring.
static void showMessage(const wchar_t *wmsg)
{
std::wcout << wmsg << std::endl;
::MessageBox(NULL, wmsg, TEXT("Message"), MB_OK);
}
static void testLoadLibrary(const wchar_t *lib)
{
::SetLastError(0L);
::SetErrorMode(0);
std::wstringstream wss;
wss << "LoadLibrary: " << lib;
showMessage(wss.str().c_str());
HINSTANCE LoadME = ::AfxLoadLibrary(lib);
if (LoadME == NULL) {
DWORD dw = ::GetLastError();
wss << "Failed: Error code " << dw;
showMessage(wss.str().c_str());
ErrorExit(lib, dw);
} else {
wss << "LoadLibrary of " << lib << " succeeded.";
showMessage(wss.str().c_str());
::FreeLibrary(LoadME);
}
}
Finally, I ran Process Monitor (sysinternals.com) to monitor the test program, looking at all entries with Path containing the string "dll." I don't see anything particularly informative in this list--no idea why the DLL is failing to load.
If I use LoadLibraryEx with DONT_RESOLVE_DLL_REFERENCES, the library loads, so this really looks like a dependency issue, which is why I'm surprised that the dependency walker isn't being particularly helpful.
I've tried this on Windows 2008 R2 and Windows 2003; same behavior.
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有一个操作系统工具可以帮助诊断此类问题。下载 SDK 或 DDK 并使用 gflags.exe 为进程设置“显示加载程序快照”(+sls)。这应该可以揭示 DLL 加载失败的原因。
加载器捕捉输出将出现在调试器输出窗口中。
马丁
There is an OS tool to help diagnose problems like this. Download the SDK or DDK and use gflags.exe to set 'Show Loader Snaps' (+sls) for the process. That should reveal why the DLL load fails.
The loader snaps output will appear in the debugger output window.
Martyn