Win 7 DllImport C#奇怪的错误,无法访问内存位置?

我正在使用DllImport从我的C#应用​​程序访问C ++ DLL中的一些函数。

这个代码在我的开发笔记本电脑上工作正常,这是Windows 7 64位,dll本身是32位,所以我运行主机在32位的dll进程,它运行良好。 但是,当我尝试在我的目标计算机上运行完全相同的进程时,Windows 7 64bit Ultimate我得到错误“无效访问内存位置”。 从过程中。

我不确定问题是什么,我看了网上的大量资源,但没有一个能为我解决。 我不明白为什么它在我的开发盒上工作正常,但不在目标上?

dll本身很好,dll附带的示例都可以在我的目标框上运行(这是C#应用程序正在执行DllImport)。

有没有其他人有这个问题? 现在已经打了两天了!

例外: {"Unable to load DLL 'CLEyeMulticam.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"}

由于未解析的依赖项,DLL加载可能会崩溃,因此使用Dependency Walker在目标计算机上打开您的DLL并查看是否存在任何问题。

我注意到您的开发机器和目标机器,开发环境之间存在很大差异。 确保在目标计算机上具有所有必需的可再发行组件。

编辑:我已经看到类似的问题,当一些dll被编译到.Net框架的不同版本或者它们是由不同版本的Visual Studio制作时,因为每个版本的可再发行组件是不同的,并且最新的可再发行组件不完全向后兼容。

我在这里有同样的问题本机加载效果很好。 从.net加载错误无法加载DLL’my.dll’:无效访问内存位置

问题出在DEPfunction上。 当我仅为基本程序打开DEP时,它没有任何效果。 但是当我完全关闭DEP并重新启动我的服务器时,错误已经消失。 我做的另一件事 – 为.net 4.0安装了最新的更新

一个值得注意的事情 – 我没有看到关于DEP的任何错误,只是因为“内存”错误而关闭。

我以前遇到过这个问题。 我认为你的问题是VS试图打开文件但没有权限阅读它。 您需要确保您使用的帐户有权访问DLL。 尝试禁用UAC以查看其是否有效,或使用管理员帐户。 或者尝试将DLL的Full Control交给Everyone

编辑:你能以管理员身份运行VS(右击 – >以管理员身份运行)吗? 你能把DLL放到你的桌面上试试吗? 您的工作计算机与失败的计算机之间是否存在文件夹结构差异? 另外,如果你在VS之外执行它,那么DLL运行是否正常(尝试以管理员身份运行它)?

HTH

我之前遇到过类似的问题,请尝试以下方法。

  • 检查.NET CLR版本。 您的目标中是否存在任何不在您的开发中的SP / KB?
  • 尝试加载C ++ DLL的调试版本。 你能加载吗? 如果失败,我建议在目标中的WinDBG下启动你的应用程序。 一旦发现exception,简单的!analyze -v将为您提供大量信息。
  • 下一步, 我将尝试在unit testing环境中重现此问题 。 您提到的C#示例是否为x64 VM构建? 如果没有,请尝试这样做并尝试在目标中运行生成的样本二进制文件。 问题是否可以重现?

我遇到了64位.NET应用程序(“任何CPU”)试图加载32位本机DLL依赖项的问题。 我面前没有错误信息,所以我不能告诉你它是否是同一个问题。 我的问题的解决方案是将我的构建更改为仅x86。

如果DLL的位大小在每个框上发生变化,则可能存在结构大小差异,因此您的PInvoke签名变得不正确。 这很容易导致缓冲区溢出,并导致本机代码中的堆栈损坏。

如果您在C#应用程序中收到错误,此消息通常表示本机代码对ILM可以看到的内存做了一些讨厌的事情 – 检查DllMain例程中/调用的代码 – 在您的调用实际通过之前调用 – 如果它行为不端,你会看到这个结果

@Merlyn Morgan-Graham我们遇到了类似的问题。 我们使用“任何CPU”构建构建.Net应用程序,并尝试使用32位C ++ Dll。 当我们在64位操作系统中运行.Net应用程序时。 它运行为64位可执行文件,因此得到类似的问题。 在X86加载后,对C ++ Dll的调用非常好。 更重要的是,如果您在.Net代码中使用C ++ DLL。 会有相当数量的编组,因此坚持构建类型(即X86,任何CPU或X64)非常重要。

请检查以下链接: Windows Vista:无法加载DLL’x.dll’:无效访问内存位置。 (DllNotFoundException)

显而易见但可能很蹩脚的解决方案是明确为32位构建C#端。 检查如何创建proc主机 – 以编程方式或通过填充注册表项或…可能是在其他框中它设置为进行64位主机进程或尝试进程内调用,这意味着加载..它是一个注册表设置不要忘记,对于混合23/64位的情况,有两个分支可以挖掘。

当我转到win7时,我遇到了类似的问题。 您可能需要使用以下命令将您的(64位)计算机设置为默认运行32位计算机:

C:\ WINDOWS \ Microsoft.NET \ Framework64 \ v2.0.50727 \ Ldr64.exe setwow

参考: http : //social.msdn.microsoft.com/Forums/en/phoenix/thread/9a43e9a1-a744-4a1a-bb34-3604254c126b