2011-10-10 32 views
8

Hay una clase SafeHandleZeroOrMinusOneIsInvalid en .NET Framework, así como una clase SafeHandleMinusOneIsInvalid.¿Es cero alguna vez un identificador válido?

¿Por qué es esto? ¿En qué situaciones cero es un identificador válido?

+0

Me imagino que hoy cero nunca es un identificador válido; en este momento estoy buscando en Process Explorer en Windows 7 y manejo los valores comienzan en 4 (clave de registro de opciones de ejecución de archivos de imagen, curiosamente). Sospecho que es de la época anterior donde quizás alguna antigua función Win16 o DOS que abría un archivo podía devolver un identificador o manejador con un valor de cero. En la actualidad, 0 y -1 son valores inválidos especiales, por lo que no puedo imaginar que alguna vez obtengas un identificador válido con ninguno de los valores. Puede examinar qué .NET API usa SafeHandleMinusOneIsInvalid; tal vez eso te dará algunos consejos. – Luke

+0

@Luke: Tal vez ... pero incluso entonces, ¿por qué les habría importado Win16/DOS cuando diseñaron SafeHandle en .NET 2.0? – Mehrdad

+0

Probablemente no haya un enlace directo, pero todo está construido sobre todo lo demás, por lo que la compatibilidad con versiones anteriores es una consideración importante. .NET 2.0 se ejecuta en Windows 98, ya sabes; eso es impresionante cuando lo piensas. – Luke

Respuesta

6

Como conferencia adicional para las otras respuestas, vea this OldNewThing blog entry acerca de los valores de retorno de identificador inconsistentes.

+0

Debe elaborar, no solo pasar un enlace. – tenfour

+0

Tienes toda la razón. Siéntete libre de editar mi respuesta, si crees que falta algo. De hecho, incluso debería haber publicado eso como comentario, ya que no responde exactamente la pregunta. Pero me habría perdido mis diez puntos: D.Además, no quería evitar que nadie descubriera el maravilloso blog de Raymond (y solo podría haber copiado el texto desde allí, lo que me pareció una pérdida de tiempo) – MartinStettner

+0

@MartinStettner: Ese es un buen enlace, pero eso no dice cualquier cosa sobre .NET wrappers, es decir, por qué 'SafeHandleMinusOneIsInvalid' existe en absoluto. +1 de todos modos, pero dudo que acepte esto. : P – Mehrdad

3

Sí. Zero es el manejador de archivo para stdin. Los identificadores que no son kernel no son válidos si son cero.

+0

http://en.wikipedia.org/wiki/File_descriptor – mellamokb

+3

Un identificador de archivo Win32 no es lo mismo que un descriptor de archivo POSIX/C – jalf

+0

Pasando 0 a ReadFile todavía lee STDIN. – Joshua

3

Como presentada por Microsoft en su documentation (y demostrado en la descripción de Joshua,) que depende de la implementación, por así decirlo:

En él se describe el formato de un identificador no válido.

Por ejemplo, algunos asas utilizan -1 como un valor de identificador no válido, mientras que otros utilizan 0. Otras derivaciones de esta clase (por ejemplo, identificadores de archivo o registro) pueden especializar más. Consulte la clase SafeFileHandle para obtener un ejemplo de una clase que se deriva de SafeHandleZeroOrMinusOneIsInvalid.

+0

Lo que es gracioso es que hace que SafeFileHandle * esté mal *. – Joshua

+2

Eso todavía no dice cuando cero es ** válido ** como un identificador ... – Mehrdad

1

Creo que está leyendo demasiado en el nombre: todo esto significa que algunas API por convención devuelven 0 para indicar la falla, otras devuelven -1. Para una API que devuelve -1, esto no significa que 0 nunca será un identificador válido, solo que la API devuelve -1 para indicar la falla.

Por lo tanto, esto realmente se trata del valor que una API suele utilizar para indicar la falla; no dice nada sobre si otros valores de identificadores son válidos o no para un conjunto determinado de API.

+0

Bien, tal vez, pero ¿cómo es que no hay una clase 'SafeHandleZeroIsInvalid'? Seguramente hay * muchas * API más que devuelven cero como un valor inválido en lugar de -1. – Mehrdad

+1

El problema clave es que la misma clase de control necesita trabajar con * ambos * tipos de API. "Cero * o * Menos uno" en este caso significa que * ambos * se consideran inválidos, no * ni/ni *. Esto permite que se use la misma clase base con la API CreateFile (devuelve INVALID_HANDLE_VALUE en caso de error) como con CreateMutex (devuelve NULL en caso de error). ¿Por qué tener dos clases base separadas (que pueden causar confusión y error si el usuario elige la incorrecta) cuando uno puede manejar ambos casos? – BrendanMcK

Cuestiones relacionadas