web-dev-qa-db-ja.com

IntPtr.Zeroはnullと同等ですか?

非同期に実行するReadFileをセットアップしようとしています [〜#〜] msdn [〜#〜] に応じて、 lpNumberOfBytesReadnullに設定します。

「これが非同期操作である場合、このパラメーターに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
  );
_

そして、私はこれを次のように呼び出します(4番目のパラメータをnullにするつもりで):

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

それはnullで呼び出すのと同じですか?そうでない場合、宣言または関数呼び出し自体で何を変更する必要がありますか?

SafeHandle参照にHandleRefの代わりにIntPtrまたはhFileを使用する必要があるかどうかにも興味がありましたか? CloseHandle(IntPtr)でハンドルを閉じることを確認することは知っていますが、IntPtrで他の2つのオプションを使用する理由があるかどうかはわかりません。また、安全でないコードの使用を避けようとしています。

編集:結局のところ、私は非同期に実行しているにもかかわらず、すぐに戻る可能性があるため、4番目のパラメータを_IntPtr.Zero_に設定するべきではありません。 Asynchronous Disk I/O を参照してください。ああ、矛盾する物語が大好きです。

57
SwDevMan81

リストしたようなP/Invokeの目的では、NULLの代わりにIntPtr.Zeroを使用する必要があります。ただし、これはC#nullキーワードと同等ではないことに注意してください。

70
Michael

値型にnullを割り当てることはできません。参照タイプは、オブジェクトインスタンスを参照しないなど、nullでもかまいませんが、値タイプには常に値があります。

IntPtr.Zeroは、nullポインターを表す単なる定数値です。

8
Yannick Motton

C#> = 2.0にはバグ(機能??)があることに注意してください。

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

正しくコンパイルされますが、ifに入ることはありません。

roslynのgithub で問題を開きましたが、warnings-as-errorsでビルドされたプロジェクトがあるため、修正しないと回答しました。これにはまだ部分的な修正があります。この警告を生成するstrictコンパイルモードがあります。

<Features>strict</Features>
7
xanatos