From: Peter Duniho on
Tony Johansson wrote:
> Hi!
>
> Here is some text from Microsoft press(exam 70-536).
>
> "Exceptions in unmanaged code are markedly different from those thrown in
> managed code. In earlier COM days, you could use the GetLastError function
> to get the last error that was raised. This approach won't work in a managed
> application because the return value of GetLastError might not be the
> correct one. Why ? because the GetLastError method can be set by either a
> ..NET framework object or the common language runtime(CLR) "
>
> What does this last sentence actually mean here. It says "because the
> GetLastError method can be set by either a .NET framework object or the
> common language runtime(CLR) "
>
> What is the difference between NET framework object or the common language
> runtime(CLR) ?

CLR is the thing that lets .NET Framework objects work. The framework
objects are, of course, the objects themselves.

Note that the [DllImport] attribute has the SetLastError field, which
you can set to true for a p/invoke declaration. This allows you to call
Marshal.GetLastWin32Error() and retrieve the actual error code set by
SetLastError(), even if the CLR or some other .NET Framework object
changes it before your own code gets control back.

Pete
From: Peter Duniho on
Tony Johansson wrote:
> So do you mean it's a good manner to use Marshal.GetLastWin32Error() after
> each unmanaged call that could cause error ?

No. You need to follow the rules for the unmanaged API, which is that
calling GetLastError() is only guaranteed to be valid if the API
function that was called returned an error status. Many, if not most,
Win32 functions return an HRESULT status code that includes the error,
but for those that don't � sometimes they return a BOOL, sometimes an
"invalid" signal value, etc. � you have to call GetLastError() to find
out what the error really is.

But if an error doesn't happen, it may or may not be the case that
calling GetLastError() would return useful information.

So, you can use the SetLastError field in the [DllImport] attribute to
ensure that the marshaler saves the error code for you to retrieve via
GetLastWin32Error(). But the error code returned by that method is
meaningless unless an error _actually_ happened. You would not actually
look at the error unless the function itself returned whatever its
particular "error happened" value is.

Pete