Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 未使用DLLImport C加载非托管DLL#_C#_Dll - Fatal编程技术网

C# 未使用DLLImport C加载非托管DLL#

C# 未使用DLLImport C加载非托管DLL#,c#,dll,C#,Dll,我一定是错过了什么;快疯了。。我正在使用VS2010 C#,用C#开发一个Windows窗体应用程序。在同一个解决方案中,我有一个C++ DLL项目,把它的DLL输出到同一个“/bin”文件夹,作为C可执行文件。我正在看文件夹,文件肯定在那里。我甚至使用以下方法来确保它在运行时存在: // yep.. it's there... string s = System.IO.Directory.GetCurrentDirectory() + @"\Foo.dll"; System.Diagnosti

我一定是错过了什么;快疯了。。我正在使用VS2010 C#,用C#开发一个Windows窗体应用程序。在同一个解决方案中,我有一个C++ DLL项目,把它的DLL输出到同一个“/bin”文件夹,作为C可执行文件。我正在看文件夹,文件肯定在那里。我甚至使用以下方法来确保它在运行时存在:

// yep.. it's there...
string s = System.IO.Directory.GetCurrentDirectory() + @"\Foo.dll";
System.Diagnostics.Debug.Assert(System.IO.File.Exists(s));
我的DLL包含以下内容:

extern "C" __declspec(dllexport) int test_func();
我用DLL资源管理器实用程序确认了它的正确名称。函数本身只执行“返回4”

C代码为:

我得到这个错误:

.exe中发生类型为“System.DllNotFoundException”的未处理异常

其他信息:无法加载DLL“Foo.DLL”:对内存位置的访问无效。(HRESULT的异常:0x800703E6)

假设您已经看到了


您是否已使用打开“foo.dll”以确保满足所有依赖项?

当框架调用
LoadLibrary
时,会发生错误。可以从错误消息中推断:

无法加载DLL“Foo.DLL”

报告的错误代码是包装Win32错误代码998(又名)的COM错误代码。导致调用
LoadLibrary
抛出
ERROR\u NOACCESS
的场景如下所述:

症状

LoadLibrary()API有时可能会遇到访问冲突 尝试将指定模块映射到的地址空间时 调用过程。在此事件中,LoadLibrary()返回的值为 NULL和GetLastError()返回错误代码998(error\u NOACCESS)。 返回顶部|给出反馈

原因

Windows NT状态代码状态\u访问\u冲突映射到 Win32错误代码错误\u无法访问。因此,如果操作系统 加载程序在运行时遇到访问冲突(异常C0000005) 映射指定的DLL文件映像或执行启动代码, 加载程序将最后一个错误设置为998(错误\u NOACCESS),并且 LoadLibrary()函数将失败,返回值为NULL。回到 高层给予反馈

更多信息

当启动代码中的任何位置发生访问冲突时 异常调度程序检测遇到此问题的进程 正在调试异常。如果是这样的话,这个第一次机会的例外是 发送到调试器

要解决LoadLibrary()故障,请在 调试器并为C0000005启用第一次机会异常处理 访问冲突异常。如果在以下情况下发生访问冲突: 调用LoadLibrary()函数时,应用程序将进入 调试器。然后,调试器的调用堆栈可用于跟踪 出现异常。堆栈跟踪应有助于缩小范围 与遇到的异常相关的实际问题

有关如何为启用首次机会异常处理的信息,请参见 C0000005访问冲突异常,请参考调试器 文件

实际上,DLL在其启动代码中产生访问冲突。很多事情都可能导致这种情况,您需要对DLL进行一些调试。我建议您尝试从本地C++主机调试这个。这样调试DLL可能会更容易


另外,你的函数使用了
cdecl
调用约定,一旦你越过了当前的障碍,你需要修改你的C#p/invoke来指定
调用约定。cdecl

是你的应用程序…32位还是64位?32位。或者我应该说我没有明确定义64位的应用程序。DLL什么也没做。它只依赖于几个stl模板头。我运行dependens.exe,只得到以下结果:错误:由于隐式依赖模块中缺少导出函数,至少有一个模块具有未解析的导入。错误:找到具有不同CPU类型的模块。我猜它在抱怨,因为DLL是32位的,我运行的是Windows 7 x64。我在我的C#应用程序中的LoadLibrary上使用了DllImport[],并将其称为返回的“0”?!?我使用了与File.Exists()完全相同的路径,所以我认为这一定是某种权限问题..不。当它失败时,它返回
LoadLibrary
返回
0
。这表明一个错误。如果在
LoadLibrary
pinvoke中包含
SetLastError=true
,则可以调用
Marshal.GetLastWin32Error
,它将返回998。这不是许可。您的DLL的
DllMain
正在引发访问冲突。你的下一步就是照我说的做。使用本机主机对此进行调试。或者研究如何从C#主机启用非托管调试。哦,天哪,我没想到会出现这种情况。。。一个全局静态类正在访问它自己的“static std::map”成员。但它似乎是在成员定义之前被访问的。我猜它没有及时初始化自己的值以供构造函数使用。我甚至认为那是不可能的!我重新排序了代码,现在它工作了。。疯狂,是的。静态初始化。抓住你了!!
[DllImport("Foo.dll")]
private static extern int test_func();