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


113

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

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

我已阅读并尝试了在互联网上找到的许多解决方案。什么都没有

我尝试使用以下方法:

[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);

当我尝试阅读本文并运行本示例(从下载的代码中)时,它可以正常运行(所用的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);

有什么建议?

Answers:


90

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

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

此外,我还要检查DLL的依赖关系,Visual Studio附带的依赖关系查询程序可以在这里为您提供帮助,也可以免费下载:http : //www.dependencywalker.com


4
发现缺少某些依赖项(Oracle和IE中的某些dll)。由于我的dll依赖于此,因此需要安装Oracle。.那时我就会知道:)发现DependencyWalker的问题;)
Ingimar Andresson 2012年

不用担心,它为我省去了数小时的头痛,这是个很棒的小工具!:-)
display101 2012年

1
向Keith Halligan +1,以建议DependencyWalker。它告诉我并非所有的依赖项都具有相同的CPU类型(x86 / x64)。我将所有具有相同CPU类型的文件复制到应用程序的bin文件夹中,从而解决了该问题。
DiligentKarma

6
我在系统上可以找到的每个dll都有DependencyWalker,它们声称不同的CPU类型都有错误-甚至是System.Web.Mvc.dll。这里有些误报。
PandaWood

2
就我而言,问题是试图加载为Debug编译的C ++ DLL。这需要C ++调试运行时,这意味着您必须安装Visual Studio。或重新编译DLL以发布,然后安装可分发的C ++运行时。
RenniePet 2014年

42

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

dumpbin /DEPENDENTS my.dll

这将告诉您您的DLL需要加载哪些DLL。特别要注意MSVCR * .dll。我没有看到未安装正确的Visual C ++可再发行组件时发生错误代码。

您可以从Microsoft网站获取“用于Visual Studio 2013的Visual C ++可再发行组件程序包”。它安装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一起安装,而不是由可再发行组件包安装。


5
对我来说,添加VS C ++可再发行组件就可以了!需要v10.0(2010)。谢谢你!
Thiago Silva

有什么方法可以判断是否需要64位或32位版本的可再发行文件?
BVB 2015年

1
dumpbin / ALL将告诉您my.dll是否为x64的x86
Anthony Hayward

1
对于仍然遭受此问题困扰的人,如果使用debug二进制文件,则C ++运行时可再发行版本必须与构建它的位置完全相同。
skyline75489 '16

@ skyline75489的评论为我节省了一天的时间。C ++库在我的计算机上运行良好,但是由于VS将其链接到msvcr的调试版本而无法在其他任何地方加载。
间谍

14

这是一个“麻烦”,您至少可以使用它进行健全性测试:尝试在代码中对DLL的路径进行硬编码

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

话说回来; 在我的情况下,dumpbin /DEPENDENTS按照@ anthony-hayward的建议运行,并将那里列出的DLL的32位版本复制到我的工作目录中,为我解决了这个问题。

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


12

DLL必须位于bin文件夹中。

在Visual Studio中,我将dll添加到我的项目中(“引用”中没有,而是“添加现有文件”)。然后将dll的“复制到输出目录”属性设置为“如果更新则复制”。




4

有一件非常有趣的事情(并且与技术相关)可能会浪费您的时间,因此请考虑在此处共享它-

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

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

我一直在

无法加载DLL

错误数小时。后来我意识到,所有要加载的非托管程序集都需要复制到\bin\debug启动项目的目录中,该目录ConsoleApplication1通常是一个Win窗体,控制台或Web应用程序。

因此,请谨慎地Current Directory接受答案中实际上意味着Current Directory从您的应用程序开始启动的主要可执行文件。看起来很明显,但有时可能并非如此。

获得的经验教训 –始终将非托管dll与启动可执行文件放在同一目录中,以确保可以找到它。


这也为我解决了问题。不过,将DLL放入主项目而不是实际使用它们的项目中感觉很奇怪……
Sean Duggan

@SeanDuggan是因为它是“动态链接库”,这意味着它在运行时使用(加载),而不是在链接时使用静态库。
m4l490n

我尝试将dll添加到bin\Debugobj\Debug目录中,但不断收到“无法加载DLL”
m4l490n

3

打开融合日志记录,有关如何执行此操作的大量建议,请参阅此问题。调试混合模式应用程序的加载问题可能会很痛苦。融合日志记录可以提供很大的帮助。


2

确保将“构建平台目标”设置为x86或x64,以便它与您的DLL兼容-DLL可能是为32位平台编译的。


2

如果DLL和.NET项目在同一解决方案中,并且您希望每次都编译并运行,则可以右键单击.NET项目的属性Build events,然后在Post-build event中添加如下所示的内容命令行:

copy $(SolutionDir)Debug\MyOwn.dll .

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


2

在将应用程序部署到PC时,我遇到了同样的问题。这个问题是开发了PC msvcp110d.dllmsvcr110d.dll,但没有测试PC。

我在InstalledSheild中添加了“ Visual Studio C ++ 11.0 DebugCRT(x86)”合并模块,它可以正常工作。希望这对其他人有帮助。


2

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

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


1

我认为您的非托管库需要清单。
是将其添加到二进制文件中的方法。与是为什么。

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


1

设定:32位Windows 7

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

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

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

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

问题已解决。

出人意料的是,并非所有依赖模块都已解决。不过,现在可以引用* .dll。


1

我遇到了同样的问题,以我为例,我有两台32位PC。一台装有.NET4.5的计算机,另一台是全新的PC。

我的32位cpp dll(发布模式生成)在安装.NET的PC上工作正常,但在新PC上却无法正常工作,出现以下错误

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

最后,

我只是在调试模式配置构建了项目,这一次我的cpp dll运行正常。


0

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

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

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

3.Checked如果PDB(程序数据库)文件missing.This 视频使您最了解pdb文件。

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


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.