web-dev-qa-db-fra.com

IntPtr.Zero est-il équivalent à null?

J'essaie de configurer ReadFile pour qu'il s'exécute de manière asynchrone et selon MSDN , je dois définir lpNumberOfBytesRead sur null:

"Utilisez NULL pour ce paramètre s'il s'agit d'une opération asynchrone pour éviter des résultats potentiellement erronés."

Par exemple, si j'ai les éléments suivants:

  [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
  );

et je l'appelle comme ça (avec l'intention d'avoir le 4ème paramètre nul):

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

sera-ce la même chose que de l'appeler avec null? Sinon, que dois-je changer dans la déclaration ou dans l'appel de fonction lui-même?

J'étais également curieux de savoir si je devrais utiliser SafeHandle ou HandleRef au lieu de IntPtr pour la référence hFile? Je sais que je ferme la poignée avec CloseHandle(IntPtr) lorsque j'en ai fini, mais je ne sais pas s'il y a une autre raison d'utiliser les deux autres options sur IntPtr. J'essaie également d'éviter d'utiliser du code dangereux.

EDIT: En fin de compte, je ne devrais pas définir le quatrième paramètre sur IntPtr.Zero De toute façon, car même si j'exécute de manière asynchrone, il pourrait toujours revenir immédiatement. Voir E/S de disque asynchrone . Ahh, j'adore les histoires contradictoires.

57
SwDevMan81

À des fins de P/Invoke comme vous l'avez indiqué, vous devez utiliser IntPtr.Zero à la place de NULL. Notez cependant que ce n'est pas équivalent au mot clé C # null.

70
Michael

Vous ne pouvez pas affecter null à un type de valeur. Un type de référence peut être nul, comme dans, ne faisant pas référence à une instance d'objet, mais un type de valeur a toujours une valeur.

IntPtr.Zero est juste une valeur constante qui représente un pointeur nul.

8
Yannick Motton

Sachez qu'il existe un bogue (fonctionnalité ??) dans C #> = 2.0, où

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

sera compilé correctement, mais il n'entrera jamais dans le if.

J'ai ouvert un problème sur le github of roslyn et ils ont répondu qu'ils ne le corrigeraient pas car il y a des projets qui sont construits avec des avertissements en tant qu'erreurs. Il existe toujours un correctif partiel pour cela: il existe un mode de compilation strict qui génère cet avertissement:

<Features>strict</Features>
7
xanatos