pinvoke - P/Inoke 捕获 native 异常

标签 pinvoke

我正在测试一个 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/

相关文章:

c++ - PInvoke 返回带有二维数组的结构

c# - 缓冲区是从共享堆中为大小为 64 KB 的进程分配的?

c# - 是否可以通过 P/Invoke 从 C# 使用 D?

c# - 将字符串从 c# 传递到 c++ dll

c# - 查找包含进程特定文本的窗口

C# P/调用 : native output parameter value won't reach managed code

C# P/Invoke void** 指针传递

c# - 方法的类型签名与 PInvoke 不兼容

.net - 在编码包装通过传递接口(interface)句柄工作的 C++ 接口(interface)(全部抽象)时 Intptr 是否足够?

.net - 检测笔记本电脑盖子的关闭和打开