62 votes

IntPtr.Zero est-il équivalent à null ?

J'essaie de mettre en place ReadFile pour s'exécuter de manière asynchrone et en fonction de MSDN Je dois définir lpNumberOfBytesRead a null :

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

Par exemple, si j'ai ce qui suit :

  [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 ainsi (avec l'intention que le quatrième paramètre soit nul) :

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

Cela reviendra-t-il à l'appeler avec null ? Si ce n'est pas le cas, que dois-je changer dans la déclaration ou dans l'appel de la fonction elle-même ?

Je me demandais également si je devais utiliser SafeHandle o HandleRef au lieu de IntPtr pour les hFile référence ? Je sais que je dois m'assurer que je ferme la poignée avec CloseHandle(IntPtr) quand j'en aurai terminé, mais je ne sais pas s'il y a d'autres raisons d'utiliser les deux autres options plutôt que les deux premières. IntPtr . J'essaie également d'éviter d'utiliser du code non sécurisé.

EDIT : Il s'avère que je ne devrais pas fixer le quatrième paramètre à IntPtr.Zero de toute façon, parce que même si je fonctionne de manière asynchrone, il pourrait quand même revenir tout de suite. Voir E/S disque asynchrones . Ahh, j'aime les histoires contradictoires.

77voto

Michael Points 34110

Pour les besoins de P/Invoke tels que vous les avez énumérés, vous devez utiliser IntPtr.Zero à la place de NULL . Notez que cela n'est pas équivalent à la méthode C# null Toutefois, le mot-clé n'a pas été retenu.

8voto

Yannick Motton Points 9806

Vous ne pouvez pas attribuer la valeur null à un type de valeur. Un type de référence peut être nul, c'est-à-dire qu'il ne fait 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.

2 votes

Apparemment, IntPtr est Chuck Norris. Il peut comparer à null, mais jamais être vrai dans cette comparaison.

7voto

xanatos Points 30513

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 fichier if .

J'ai ouvert un dossier sur le site github de roslyn et ils m'ont répondu qu'ils ne le corrigeraient pas parce que certains projets sont construits avec des avertissements en tant qu'erreurs. Il y a tout de même une solution partielle à ce problème : il y a une fonction strict qui génère cet avertissement :

<Features>strict</Features>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X