1

我正在测试一个 C# .NET 4.0 应用程序,它通过 PInvoke 与 C++ 非托管 DLL 交互,我想捕获 dll 引发的任何异常。我在 try/catch 子句中包装了 dll 函数来处理本机异常,但是当它被触发时,它被忽略了。试过:

try { } catch {}
try {} catch (Exception)
try {} catch (SEHException)
try {} catch (Win32Exception)

无济于事

唯一可行的选项是将DllImport SetLastError属性设置为 true 并在调用函数检查后使用:

if (Marshal.GetLastWin32Error() !=0) 

这是一个令人满意的解决方案,但我只是想知道为什么其他选项没有任何效果,以及想知道本机异常是由非托管 dll 还是由 Windows API 本身触发的,因为例如异常是:

System.ComponentModel.Win32Exception (0x80004005): There is not enough space on the disk

这是来自 Windows API 本身的通知吗?

4

1 回答 1

2

简单的解释是本机代码不会抛出异常。是的,使用 GetLastWin32Error() 是任何 Windows api 函数的样板。其他代码也可能使用它,虽然它不是很常见,但任何人都可以调用 SetLastError() 来设置线程的错误代码。否则 C 代码永远不会故意抛出异常,该语言不支持它。

0x80004005 错误代码是 COM 错误代码 E_FAIL。您不使用 pinvoke 调用 COM 函数,CLR 对 COM 互操作的支持通过导入库来处理它。您确实会收到 COM 错误的异常,当 CLR 看到 COM 方法返回失败代码时会抛出异常。它还使用 IErrorInfo 来获得错误代码的更好描述,在 Exception.Message 属性中返回。

于 2012-07-13T17:38:40.380 回答