2009-06-27 191 views
15

我在与调用LoadLibrary(麻烦),并得到一个错误,没有任何意义对我说:调用LoadLibrary()错误代码127

::SetLastError(0); 

    m_hDll = ::LoadLibrary(szName); 

    if (m_hDll == NULL) // Failure to load the DLL. 
    { 
     DWORD err = GetLastError(); 
    } 

的错误127(“指定的程序不能找到。“)对LoadLibrary()的调用我没有任何意义。我还没有调用GetProcaddress()。

DLL(和应用程序)都是用VS ++ 2005 SP1编译的。

可能会出现什么问题?

+0

也许图书馆里没有`DllMain`?它应该失败`:: LoadLibrary`? – 2010-03-17 17:21:19

+0

如果`DllMain`将'最后一个错误'设置为127,然后返回'FALSE`,那么在':: LoadLibrary`返回之前系统会覆盖'最后一个错误'吗? – 2010-03-17 17:25:29

回答

4

错误消息意味着找到了合适的DLL,但缺少所需的过程导出。你有正确的DLL版本吗?

您可以使用dumpbin.exe来检查DLL导出的功能并检查拼写。

+1

我还没有调用过GetProcAddress()。什么导出可能会丢失? – 2009-06-27 17:22:02

2

您的应用程序和DLL使用的运行时间不匹配吗?

过去,VS 2005让我感到困惑的一个问题是,其中一部分构建为发布版本,另一部分构建为调试版本。这些拉动不兼容的Microsoft运行时DLL的不同版本,因为只能在给定进程中加载​​一个DLL。

我认为你看到错误127的原因是因为你的DLL在加载的运行时DLL中寻找一个不存在的函数,因为它是错误的运行时。

0

我的两个猜测
1. LoadLibrary调用指定DLL的DllMain(第一次尝试并附加到您的过程)。远射,但它在那里?
2. LoadLibrary将加载指定的DLL及其所有依赖项。因此,如果DLL的依赖模块不能位于这将导致加载失败的搜索路径 - 你可以用于depends.exe检查 - 可here

19

让我们一步一步来:

  1. 错误消息表示找到了dll,但缺少必需的功能。 (抖动是正确的。)这意味着你有你需要的DLL,但不是正确的版本。 (Davefiddes是对的,虽然问题可以是任何DLL,而不仅仅是Microsoft运行时库,并且,至少对于主要更新,Microsoft为其运行时库提供了不同的名称,所以在这种情况下,这不是问题。)

  2. 这没有意义,因为没有函数被请求从被加载的dll。 (亚当是对的)

  3. 因此,缺少的函数应该被发现不在被LoadLibrary命令显式加载的dll中,而是在一个依赖的dll中被同时隐式加载,因为第一个DLL需要它。 (Zebrabox已关闭。)

  4. 依赖的dll是一个dll,它“静态”链接到正在显式加载的库,通过导入库或.lib文件包含在显式加载的dll的链接器步骤中。 (我敢打赌,你不知道一个“动态链接库”可能会“静态链接”。好吧,现在你已经做到了。)

  5. 如果您在不同的文件夹同一个DLL的多个版本,那么这可能也是一个搜索路径的问题(如zebrabox建议)。 Dll路径搜索顺序本身是一个复杂的主题:请参阅http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx。这取决于操作系统等。最实际的最安全的方法是将所有潜在的问题DLL放在与exe相同的文件夹中。

  6. 相关DLL也可以有自己的依赖DLL,它可以使这个问题很难解决。取决于可能会有帮助,但如果没有,请尝试使用filemon。在错误消息之前成功读取的最后一个dll是错误版本的dll。

0

我在调用LoadLibrary()后得到相同的错误代码。最后通过依赖walker发现模块(szName)的一些依赖关系丢失。

4

安装调试工具和运行gflags -i your_application.exe +sls。之后,在调试器下执行应用程序以捕获加载程序跟踪。

5

微软gflags工具会随时告诉你到底是什么依赖性无法加载和原因。

运行gflags -i your_application.exe +sls。之后,在调试器下执行应用程序以捕获loader traces

gflags是Debugging Tools的一部分 - 您可以检查C:\Program Files (x86)\Windows Kits\10\Debuggers\x64以查看是否已拥有它。您可以将该目录添加到您的路径中,或者仅在cmd.exe中执行该目录中的gflags。

例如,在运行gflags之后,在::LoadLibrary(_T("foo"))调用中放置一个断点并在您的Visual Studio输出窗口中查找加载器错误时跳过它,例如,

4b00:396c @ 479194074 - LdrpSnapThunk - ERROR: Procedure "[email protected][email protected]@[email protected]" could not be located in DLL "bar.dll" 
First-chance exception at 0x0000000077307EF8 (ntdll.dll) in your_application.exe: 0xC0000139: Entry Point Not Found. 
4b00:396c @ 479194074 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapIAT raised exception 0xc0000139 
    Exception record: .exr 0000000000129070 
    Context record: .cxr 0000000000128B80 
4b00:396c @ 479194074 - LdrpHandleOneOldFormatImportDescriptor - ERROR: Snapping the imports from DLL "C:\test\64Debug\foo.DLL" to DLL "C:\test\64Debug\bar.dll" failed with status 0xc0000139 

这意味着foo.dll负载时,依赖bar.dll是进口,而进口bar.dll失败。

的依赖进口失败,因为程序[email protected][email protected]@[email protected]不见了 - 你可以demangle,为public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64

你可能有依赖的错版 - 也许你需要重建的依赖得到它最新的。


之后运行gflags -i your_application.exe -sls禁用加载程序跟踪。