Search code examples
pinvoke

P/Inoke catching native exception


I am testing a C# .NET 4.0 application which interacts with an C++ unmanaged DLL through PInvoke and I'd like to catch any exceptions thrown by the dll. I have the dll function wrapped in try/catch clause to handle the native exception, but when it gets fired it is ignored. Tried :

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

to no avail

The only option that works is by setting the DllImport SetLastError property to true and after calling the function checking with :

if (Marshal.GetLastWin32Error() !=0) 

It is a satisfactory solution but I just wonder why the other options do not have any effect as well as wonder if if the native exception is fired by the unmanaged dll or by the Windows API itself since for example the exception is a :

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

is that a notification from the Windows API itself ?


Solution

  • The simple explanation is that the native code just doesn't throw an exception. And yes, using GetLastWin32Error() is boiler plate for any Windows api function. Other code might use it too, although it isn't terribly common, anybody can call SetLastError() to set the thread's error code. C code otherwise never intentionally throws exceptions, the language doesn't support it.

    The 0x80004005 error code is COM error code, E_FAIL. You don't use pinvoke to call COM functions, the CLR's support for COM interop takes care of it through an import library. You do get exceptions for COM errors, the CLR throws them when it sees that the COM method returned a failure code. It also uses IErrorInfo to get a better description for the error code, returned in the Exception.Message property.