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.
À 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
.
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.
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>