无法加载DLL(无法找到模块HRESULT:0x8007007E)

时间:2012-01-25 12:55:51

标签: c# c++ dll pinvoke

我的dll库包含我需要在.NET 4.0应用程序中使用的非托管C ++ API代码。但是我尝试加载我的DLL的每种方法都会出错:

  

无法加载DLL“MyOwn.dll”:找不到指定的模块。 (HRESULT异常:0x8007007E)

我已阅读并尝试过在互联网上找到的severa解决方案。什么都行不通..

我尝试过使用以下方法:

[DllImport("MyOwn.dll",  CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
    string WorkDirectory, ref StringBuilder ErrorMessage);

当我尝试关注this article并运行此示例时(从下载的代码中),它运行时没有问题(使用的dll位于bin / debug文件夹中)

我已将我的dll(以及它所依赖的所有文件复制到我的bin文件夹中)。

我也试过这种方法但得到了同样的错误:

[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern  int MyproIni(string DBname, string DBuser_pass, 
    string WorkDirectory, ref StringBuilder ErrorMessage);

有什么建议吗?

19 个答案:

答案 0 :(得分:83)

根据我在Windows上的记忆,dll的搜索顺序是:

  1. 当前目录
  2. 系统文件夹,C:\windows\system32 or c:\windows\SysWOW64(对于64位方框上的32位进程)。
  3. Path环境变量
  4. 中读取

    另外我会检查DLL的依赖关系,Visual Studio提供的依赖walker可以帮助你,也可以免费下载它:http://www.dependencywalker.com

答案 1 :(得分:36)

您可以使用dumpbin工具找出所需的DLL依赖项:

dumpbin /DEPENDENTS my.dll

这将告诉您DLL需要加载哪些DLL。特别注意MSVCR * .dll。我已经看到在未安装正确的Visual C ++ Redistributable时出现错误代码。

您可以获得Visual Studio 2013的#34; Visual C ++ Redistributable Packages"来自微软网站。它安装c:\ windows \ system32 \ MSVCR120.dll

在文件名中,120 = 12.0 = Visual Studio 2013。

请注意,您的DLL目标平台具有正确的Visual Studio版本(10.0 = VS 10,11 = VS 2012,12.0 = VS 2013 ...)正确的架构(x64或x86),以及你还需要小心调试版本。 DLL的调试版本依赖于MSVCR120d.dll,它是库的调试版本,它与Visual Studio一起安装,但不是由Redistributable Package安装。

答案 2 :(得分:10)

尝试输入dll的完整路径。 如果它不起作用,请尝试将dll复制到system32文件夹中。

答案 3 :(得分:10)

DLL必须位于bin文件夹中。

在Visual Studio中,我将dll添加到我的项目中(不是在引用中,而是“添加现有文件”)。然后将dll的“Copy to Output Directory”属性设置为“Copy if newer”。

答案 4 :(得分:5)

这是一个'kludge'你至少可以用它进行健全性测试: 尝试在代码中对DLL的路径进行硬编码

[DllImport(@"C:\\mycompany\\MyDLL.dll")]

说完了;在我的案例中,正如@ anthony-hayward所建议的那样运行dumpbin /DEPENDENTS,并将那里列出的 32位版本的DLL复制到我的工作目录中解决了这个问题。

该消息只是有点误导,因为它不是“我的”无法加载的dll - 它是依赖项

答案 5 :(得分:4)

确保您自己的dll的所有依赖项都存在于dll附近或System32中。

答案 6 :(得分:4)

有一个非常有趣的事情(并且具有技术相关性)可能会浪费你的时间,所以想到在这里分享它 -

我创建了一个控制台应用程序项目ConsoleApplication1和一个类库项目ClassLibrary1

进行p / invoke的所有代码都出现在ClassLibrary1.dll中。因此,在从visual studio调试应用程序之前,我只是将C ++非托管程序集(myUnmanagedFunctions.dll)复制到\bin\debug\项目的ClassLibrary1目录中,以便CLR可以在运行时加载它。

我一直得到

  

无法加载DLL

小时的错误。后来我意识到所有需要加载的非托管程序集都需要复制到启动项目\bin\debug的{​​{1}}目录中,该目录通常是win表单,控制台或Web应用程序。 / p>

因此,请谨慎接受答案中的ConsoleApplication1实际上意味着应用程序进程开始的主要可执行文件的Current Directory。看起来很明显,但有时可能不是这样。

经验教训 - 始终将未管理的dll放在与启动可执行文件相同的目录中,以确保找到它。

答案 7 :(得分:3)

启用融合日志记录,请参阅this question以获取有关如何执行此操作的大量建议。调试混合模式应用程序加载问题可能是一个正确的皇家痛苦。融合日志记录可以提供很大的帮助。

答案 8 :(得分:2)

当我部署我的应用程序来测试PC时,我遇到了同样的问题。问题是开发PC有msvcp110d.dllmsvcr110d.dll但不是测试PC。

我添加了#34; Visual Studio C ++ 11.0 DebugCRT(x86)"在InstalledSheild中合并模块并且它工作正常。希望这对其他人有所帮助。

答案 9 :(得分:2)

如果DLL和.NET项目在同一个解决方案中,并且您希望每次都编译并运行它们,则可以右键单击.NET项目的属性,构建事件,然后将以下内容添加到Post -build事件命令行:

copy $(SolutionDir)Debug\MyOwn.dll .

它基本上是一个DOS行,你可以根据你的DLL的构建位置进行调整。

答案 10 :(得分:2)

确保将Build Platform Target设置为x86或x64,以便它与您的DLL兼容 - 可能是为32位平台编译的。

答案 11 :(得分:1)

设置:32位Windows 7

上下文:安装了由于上述问题我无法通过的PCI-GPIB驱动程序。

简答:重新安装驱动程序。

长答案: 我还使用了Dependency Walker,它确定了几个缺少的依赖模块。我立刻认为它一定是一个拙劣的驱动程序安装。我不想检查和恢复每个丢失的文件。

我无法在控制面板的“程序和功能”下找到卸载程序,这是安装错误的另一个指标。我不得不手动删除\ system32和注册表项中的几个* .dll以允许重新安装驱动程序。

问题已修复。

意外的部分是并非所有依赖模块都已解决。然而,现在可以引用感兴趣的* .dll。

答案 12 :(得分:1)

我遇到了同样的问题,在我的情况下,我有两个32位的电脑。 一个安装了.NET4.5,另一个安装了新PC。

我的32位cpp dll(发布模式版本)在.NET安装的PC上工作正常,但没有新PC,我得到以下错误

  

无法加载DLL' PrinterSettings.dll':指定的模块无法加载   找到。 (HRESULT异常:0x8007007E)

最后,

  

我刚刚在调试模式配置中构建了我的项目,这次是我的   cpp dll工作正常。

答案 13 :(得分:1)

在我的情况下,一个不受管理的dll依赖于另一个丢失的dll。在这种情况下,错误将指向现有的dll,而不是缺少的dll,这可能会造成混淆。

这正是我的情况。希望这对其他人有帮助。

答案 14 :(得分:0)

我认为你的非托管图书馆需要一个清单 Here是如何将其添加到二进制文件中的。和here就是原因。

总之,您的盒子中可以安装几个可再发行的库版本,但其中只有一个应该满足您的应用程序,它可能不是默认的,因此您需要告诉系统您的库需要的版本,这就是为什么清单。

答案 15 :(得分:0)

在c#环境中使用非托管的c / c ++ dll文件时,也会遇到相同的问题。

1。检查dll与32位或64位CPU的兼容性。

2。检查DLL .bin文件夹,system32 / sysWOW64或给定路径的正确路径。

3。检查是否缺少PDB(程序数据库)文件。此video为您提供最好的解决方案   不了解pdb文件。

在64位系统中运行32位C / C ++二进制代码时,由于平台不兼容,可能会出现这种情况。您可以从Build>配置管理器中更改它。

答案 16 :(得分:0)

在.Net Framework +4中导入C ++ Dll时,我遇到了同样的问题,我没有选中Project-> Properties-> Build-> Prefer 32-bit,它为我解决了。

答案 17 :(得分:0)

无法加载 DLL 'xxx.dll': 找不到指定的模块。(来自 HRESULT 的异常:0x8007007E)”表示可以找到文件 CAN但它无法加载它。尝试将 DLL 文件复制到应用程序的根文件夹,一些 DLL 库需要在应用程序的根文件夹中可用才能工作。或者检查它是否有其他依赖的DLL文件。

找不到 DLL 'xxx.dll': ...”表示找不到文件无法。尝试检查路径。例如,[DllImport(@"\Libraries\Folder\xxx.dll")]

答案 18 :(得分:0)

如果您检查了所有依赖项并且您知道所有依赖项都与依赖项无关,这与文件位于错误目录中或传递给 dll 的 ARGUMENTS 不正确无关,DLL 无法加载使用LoadLibrary 本身.. 您可以检查从 LoadLibrary 返回的地址始终为 0x0000000(未加载)。

我无法弄清楚这个错误,它在 Windows 7 上运行良好,但在 Windows 10 上不起作用。我解决了这个问题,尽管它与缺少依赖项或运行时可再发行包无关。

问题是我必须用 upx 打包 DLL,然后它又开始工作了。

在旧的 Windows XP 操作系统上解压和编译文件的原因造成了错误的 PE 标头或错误的文件格式或其他东西,但是使用 UPX 打包它现在可以正常工作并且 DLL 小了 3 倍哈哈。

>