2009-09-21 14 views
48

Estoy intentando fijar ReadFile para funcionar de forma asíncrona y de acuerdo con MSDN, tengo que configurar lpNumberOfBytesRead a null:¿IntPtr.Zero es equivalente a nulo?

"Usar NULL para este parámetro si se trata de una operación asincrónica para evitar resultados potencialmente erróneas."

Por ejemplo, si tengo el siguiente:

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

y yo lo llamo así (con la intención de tener el cuarto parámetro es nulo):

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

voluntad que ser lo mismo que llamarlo con nulo? Si no, ¿qué debería cambiar en la declaración o en la llamada a la función en sí?

También era curioso si que debería usar SafeHandle o HandleRef en lugar de IntPtr para la referencia hFile? Sé que debo asegurarme de cerrar el identificador con CloseHandle(IntPtr) cuando termine con él, pero no estoy seguro si hay alguna otra razón para usar las otras dos opciones sobre IntPtr. También estoy tratando de evitar el uso de código inseguro.

EDITAR: Resulta que, de todos modos, no debería establecer el cuarto parámetro en IntPtr.Zero, porque aunque estoy ejecutando de forma asíncrona, podría volverse de inmediato. Ver Asynchronous Disk I/O. Ahh, amo historias contradictorias.

Respuesta

60

Para propósitos de P/invocar como los que ha enumerado, debe usar IntPtr.Zero en lugar de NULL. Sin embargo, tenga en cuenta que esto no es equivalente a la palabra clave C# null.

6

No puede asignar null a un valor-tipo. Un tipo de referencia puede ser nulo, como en, sin referirse a una instancia de objeto, pero un tipo de valor siempre tiene un valor.

IntPtr.Zero es solo un valor constante que representa un puntero nulo.

6

Tenga en cuenta que hay un error (función ??) en C#> = 2.0, donde

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

se compilará correctamente, pero no entrará jamás en el if.

Hay un error abierto en el Microsoft connect pero es bastante antiguo y no hay ningún comentario del personal de Microsoft.

+12

Lo siento por la publicación posterior, pero eso no es un error ya que IntPtr.Zero no es igual a nulo, por lo que si la declaración no funcionara. – Kobunite

+0

@Kobunite Luego intente escribir 'if (IntPtr.Zero ==" Hello ")' y vea qué sucede. Habrá un error en tiempo de compilación ... El problema es que no hay advertencia de que la comparación es imposible y no hay error. El código simplemente lo elimina el compilador. Ver el código IL generado http://goo.gl/6zpPxN – xanatos

+0

Lo siento por necro, pero se compila porque está utilizando efectivamente la sobrecarga del operador '==' al reparto implícito como '(IntPtr?) IntPtr.Zero == (IntPtr?) null' – Marc