2010-03-21 170 views

回答

7

我確信有一種方法,但它可能是一個壞主意。你如何保證運行時在其內部處理過程中沒有調用過一些CRT函數,這影響了errno

出於同樣的原因,您也不應直接撥打GetLastErrorDllImportAttribute提供了一個SetLastError屬性,因此運行時知道立即捕獲最後一個錯誤並將其存儲在託管代碼可以使用Marshal.GetLastWin32Error讀取的位置。

我認爲在這種情況下你可以做的最健壯的事情是製作一個C DLL,它執行實際C工作和捕獲errno。 (請注意,僅在errno捕獲周圍編寫封裝將仍然存在上述問題。)

+0

是的,我同意這一點。將C wrapper設置爲目標函數可能會更好,該目標函數將依次從中返回errno的值。 – supercheetah 2010-03-21 08:38:25

2

是的,有可能 - GetLastError確實如此。但是,正如二進制編碼器指出的那樣,您不應該直接執行此操作 - 相反,您需要在DllImport上設置SetLastError以自動執行並緩存該操作(並避免多線程問題或運行時調用的函數修改errno值) - 然後,在調用P /調用函數,檢查它的返回狀態,如果它顯示錯誤條件 - 拋出Win32Exception,它會自動讀取上次錯誤的值。是的,即使在Linux上的Mono上也是如此。

2

解決方法是在DllImport上使用SetLastError。這將使運行時間保存最後的錯誤,因此可以從Marshal.GetLastWin32Error訪問它。

有兩個問題直接調用GetLastError

  • 你能得到最後一個錯誤
  • 多個.NET線程可以駐留在同一本地之前運行時可能會在以後的PInvoke做的某個時候返回線。這會導致2個執行PInvokes的.NET線程,本地庫不知道任何更好的結果,會覆蓋最後一個錯誤。因此,.NET中的線程A獲取線程B的最後一個錯誤(可能)。
+0

您能否在'DllImport'上顯示使用'SetLastError'的語法示例? – 2015-04-16 06:55:21