1

我有一个从 Visual Studio 2003 .NET 转换为 Visual Studio 2010 的项目。它不是 .NET 项目;它不是 .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 上试过这个;相同的行为。

有什么建议么?

4

1 回答 1

4

有一个操作系统工具可以帮助诊断此类问题。下载 SDK 或 DDK 并使用 gflags.exe 为进程设置“显示加载程序快照”(+sls)。这应该可以揭示 DLL 加载失败的原因。

加载程序快照输出将出现在调试器输出窗口中。

马丁

于 2011-05-27T15:51:32.407 回答