2009-09-21 44 views
48

我試圖建立ReadFile異步運行,並根據MSDN,我需要設置lpNumberOfBytesReadnull:「使用NULL這個參數,如果這是一個異步操作,以避免潛在的錯誤結果」IntPtr.Zero是否等於null?

例如,如果我有以下:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern bool ReadFile(
    IntPtr hFile, 
    out byte[] aBuffer, 
    int cbToRead, 
    IntPtr cbThatWereRead, 
    ref OVERLAPPED pOverlapped 
); 

和我這樣稱呼它(與具有第四參數是空值的意圖):

Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped); 

意志與使用null調用它相同嗎?如果不是,我應該在聲明或函數調用中更改哪些內容?

我也好奇,如果我應該使用SafeHandleHandleRef代替IntPtrhFile參考?我知道要確保在完成後關閉手柄CloseHandle(IntPtr),只是不確定是否有其他原因使用IntPtr以上的其他兩個選項。我也試着避免使用不安全的代碼。

編輯:事實證明,我不應該設置第四個參數IntPtr.Zero無論如何,因爲即使我異步運行,它仍然可以立即返回。見Asynchronous Disk I/O。啊,我喜歡矛盾的故事。

回答

60

對於您列出的P/Invoke目的,您應該使用IntPtr.Zero代替NULL。請注意,這不等同於C#null關鍵字,但是。

6

您不能將null分配給值類型。引用類型可以爲null,因爲在不引用對象實例的情況下,值類型始終具有值。

IntPtr.Zero只是一個表示空指針的常量值。

6

要知道,有在C#> = 2.0的錯誤(功能?),其中

if (IntPtr.Zero == null) 
{ 
    // Won't enter here 
} 

會被正確編譯,但在if它永遠不會進入。

Microsoft connect上有一個bug,但它已經很老了,並且沒有任何來自微軟人員的評論。

+12

對不起,因爲IntPtr.Zero不等於null,所以if語句無效。 – Kobunite 2013-04-04 08:31:20

+0

@Kobunite然後嘗試編寫'if(IntPtr.Zero ==「Hello」)'看看會發生什麼。會有一個編譯時錯誤...問題是沒有警告,比較是不可能的,也沒有錯誤。該代碼僅由編譯器刪除。看到生成的IL代碼http://goo.gl/6zpPxN – xanatos 2015-09-02 15:40:35

+0

對不起,但它編譯,因爲它有效地使用'=='操作符重載隱式轉換爲'(IntPtr?)IntPtr.Zero ==(IntPtr? )null' – Marc 2015-12-11 20:00:37