Access C global variable 'errno' from C#
I'm fairly sure that there is a way, but it probably is a bad idea. How would you guarantee that the runtime has not called some CRT function during its internal processing that has affected the errno
?
For the same reason, you should not call GetLastError
directly either. The DllImportAttribute
provides a SetLastError
property so the runtime knows to immediately capture the last error and store it in a place that the managed code can read using Marshal.GetLastWin32Error
.
I think the most robust thing you could do in this case is make a C DLL that performs both the actual C work and the capture of the errno
. (Note that just writing a wrapper around the errno
capture would still have the concerns mentioned above.)
Yes, it is possible - GetLastError
does exactly that. However, as binarycoder pointed out, you should not do this directly - instead, set SetLastError
on your DllImport
to have this performed and cached automatically (and to avoid multithreading problems or runtime-invoked functions modifying the errno
value) - then, on invoking the P/Invoked function, check it's return status, and if it's showing an error condition - throw Win32Exception
, which reads the value of last error automatically. Yes, even on Mono on Linux.
The solution is to use SetLastError
on DllImport
. This will make the runtime save the last error so it can be accessed from Marshal.GetLastWin32Error
.
There are two problems with calling GetLastError
directly:
- The runtime might do sometime after the PInvoke returns before you are able to get the last error
- Multiple .NET threads can reside on the same native thread. This can result in 2 .NET threads doing PInvokes, native libraries not knowing any better, would then overwrite the last error. So thread A in .NET getting thread B's last error (potentially).