簡體   English   中英

有沒有辦法清除 GetLastWin32Error 的值?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM