我正在测试一个 C# .NET 4.0 应用程序,该应用程序通过 PInvoke 与 C++ 非托管 DLL 交互,我想捕获该 dll 引发的任何异常。 我将 dll 函数包装在 try/catch 子句中来处理 native 异常,但是当它被触发时,它会被忽略。尝试过:
try { } catch {}
try {} catch (Exception)
try {} catch (SEHException)
try {} catch (Win32Exception)
没用
唯一有效的选择是将 DllImport SetLastError 属性设置为 true 并 调用函数后检查:
if (Marshal.GetLastWin32Error() !=0)
这是一个令人满意的解决方案,但我只是想知道为什么其他选项没有任何效果,并且想知道 native 异常是否是由非托管 dll 或 Windows API 本身触发的,因为例如异常是:
System.ComponentModel.Win32Exception (0x80004005): There is not enough space on the disk
这是来自 Windows API 本身的通知吗?
最佳答案
简单的解释是 native 代码只是不会抛出异常。是的,使用 GetLastWin32Error() 是任何 Windows api 函数的样板。其他代码也可能使用它,尽管它不是很常见,但任何人都可以调用 SetLastError() 来设置线程的错误代码。否则,C 代码永远不会故意抛出异常,该语言不支持它。
0x80004005错误代码是COM错误代码E_FAIL。您不使用 pinvoke 来调用 COM 函数,CLR 对 COM 互操作的支持通过导入库来处理它。您确实会收到 COM 错误的异常,当 CLR 发现 COM 方法返回失败代码时,CLR 会抛出异常。它还使用 IErrorInfo 来获取错误代码的更好描述,并在 Exception.Message 属性中返回。
关于pinvoke - P/Inoke 捕获 native 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11475239/