[英]Is there a way to clear the value of GetLastWin32Error?
我有這么一點代碼。
[DllImport("library.dll", EntryPoint = "SomeoneElsesReadFunction")]
[return: MarshalAs(UnmanagedType.U4)]
private static extern UInt32 SomeoneElsesReadFunction(
Int16[] data,
Int16[] dataOrig,
[MarshalAs(UnmanagedType.U2)]
Int16 buffsize,
ref int smpNum,
);
然后...
var returnCode = SomeoneElsesReadFunction(Buffer, OrigBuffer, Consts.BufferSize, ref _sampleNumber);
int errorCode;
if ((errorCode = Marshal.GetLastWin32Error()) != 0)
{
throw new Exception(string.Format("Device read failed. Windows System Error Code: {0}", errorCode));
}
這發生在每秒運行多次的更廣泛的循環中。
我不斷收到errorCode
在循環的每次迭代183。 當我檢入 VS 調試器時,我可以看到在調用SomeoneElsesReadFunction()
之前最后一個 Win32 錯誤是 183,之后仍然是 183。
但是有沒有辦法在調用方法之前清除/重置這個值,所以我可以確定,當我事后檢查時,錯誤肯定發生在每次調用的方法中,而不僅僅是上次調用遺留下來的?
編輯
為了澄清與returnCode
的混淆,即使在我需要檢查的特定錯誤條件下,原始方法出於某種原因也會返回 code = 0。 因此,即使 returnCode 為 0(OK),我也需要調用GetLastWin32Error()
)。
我認為您混淆了錯誤代碼和返回值。 SetLastError
應該只在函數產生錯誤時調用,它永遠不應該執行SetLastError(0)
。 作為開發人員,您的工作是檢查函數調用是否失敗,然后找出失敗的原因。
錯誤代碼是為什么函數失敗的額外信息,但你的代碼不檢查返回值,看看是否有故障。
var returnCode = SomeoneElsesReadFunction(Buffer, OrigBuffer, Consts.BufferSize, ref _sampleNumber);
if(!returnCode) // Did it fail?
{
int errorCode;
if ((errorCode = Marshal.GetLastWin32Error()) != 0) // Why did it fail?
{
throw new Exception(string.Format("Device read failed. Windows System Error Code: {0}", errorCode));
}
}
感謝@Jake對這個問題的評論,我能夠解決這個問題。 在某些版本的 Windows™ 上, GetLastWin32Error()
的行為是不可預測的。 我發現之前 WIN32 調用中的錯誤沒有被后續成功的 WIN32 調用清除。 因此,在不先清除錯誤代碼的情況下在稍后調用后檢查時會出現誤報。
internal static class WIN32
{
[DllImport("kernel32.dll")]
internal static extern bool AllocConsole();
[DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll", SetLastError = true)]
internal static extern void SetLastErrorEx(uint dwErrCode, uint dwType);
}
請注意,我的某些導入沒有, SetLastError = true
參數。 添加此改進了錯誤代碼的一致性,但並非完全如此。
后來,……
// clear any previous WIN32 error code, otherwise
WIN32.SetLastErrorEx(0, 0);
IntPtr hWnd = WIN32.GetConsoleWindow();
if (Marshal.GetLastWin32Error() > 0) { /* do something */ }
if (hWnd == IntPtr.Zero)
{
WIN32.SetLastErrorEx(0, 0);
WIN32.AllocConsole();
if (Marshal.GetLastWin32Error() > 0) { /* do something else */ }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.