2011-10-10 16 views
8

Esiste una classe SafeHandleZeroOrMinusOneIsInvalid in .NET Framework e una classe SafeHandleMinusOneIsInvalid.zero è mai un handle valido?

Perché è questo? In quali situazioni è zero una maniglia valida?

+0

Immagino che oggi zero non sia mai un handle valido; in questo momento sto cercando in Process Explorer su Windows 7 e gestisco i valori partono da 4 (chiave di registro delle opzioni di esecuzione file immagine, interessante). Ho il sospetto che sia dell'epoca in cui forse una qualche antica funzione Win16 o DOS che apriva un file poteva restituire un handle o un descrittore con valore zero. Oggi, 0 e -1 sono valori non validi speciali, quindi non posso immaginare che tu possa mai ottenere un handle valido con entrambi i valori. È possibile esaminare quali API .NET utilizzano SafeHandleMinusOneIsInvalid; forse questo ti darà qualche suggerimento. – Luke

+0

@Luke: Forse ... ma anche allora, perché avrebbero dovuto preoccuparsi di Win16/DOS quando stavano progettando SafeHandle in .NET 2.0? – Mehrdad

+0

Probabilmente non c'era un collegamento diretto, ma tutto è costruito sopra tutto il resto, quindi la retrocompatibilità è una considerazione importante. .NET 2.0 funziona su Windows 98, lo sai; è un po 'impressionante quando ci pensi. – Luke

risposta

6

Come lezione aggiuntiva alle altre risposte, vedere this OldNewThing blog entry su valori di ritorno di handle incoerenti.

+0

È necessario elaborare, non appena passato un collegamento. – tenfour

+0

Hai perfettamente ragione. Sentiti libero di modificare la mia risposta, se pensi che manchi qualcosa. In realtà avrei dovuto postare anche questo come commento, dal momento che non risponde esattamente alla domanda. Ma mi sarei perso i miei dieci punti: D.Inoltre non volevo impedire a nessuno di scoprire il meraviglioso blog di Raymond (e ho potuto solo copiare il testo da lì, che mi sembrava una perdita di tempo) – MartinStettner

+0

@MartinStettner: Questo è un link certamente buono, ma questo non dice nulla riguardo i wrapper .NET, ovvero perché esiste SafeHandleMinusOneIsInvalid'. +1 in ogni caso, ma dubito che accetterò questo. : P – Mehrdad

3

Sì. Zero è l'handle di file per stdin. Gli handle non del kernel non sono validi se zero.

+0

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

+3

Un handle di file Win32 non corrisponde a un descrittore di file POSIX/C – jalf

+0

Il passaggio da 0 a ReadFile continua a leggere STDIN. – Joshua

3

Come avanzata da Microsoft nel proprio documentation (e ha dimostrato nella descrizione da Joshua,) è a carico di attuazione, per così dire:

Esso descrive il formato di un handle non valido.

Per esempio, alcuni maniglie utilizzano -1 come valore di handle non valido, mentre altri usano 0. Ulteriori derivazioni di questa classe (ad esempio, handle di file o di registro) can specialize this further. Vedere la classe SafeFileHandle per un esempio di una classe che deriva da SafeHandleZeroOrMinusOneIsInvalid.

+0

Ciò che è divertente è che SafeFileHandle * è errato *. – Joshua

+2

Ciò non dice ancora quando zero è ** valido ** come handle ... – Mehrdad

1

Penso che tu stia leggendo troppo nel nome: tutto ciò significa che alcune API per convenzione restituiscono 0 per indicare un errore, altri restituiscono -1. Per un'API che restituisce -1, ciò non significa che 0 sarà mai un handle valido, solo che l'API restituisce -1 per indicare un errore.

Quindi questo è il valore in genere utilizzato da un'API per indicare un errore; non dice nulla se altri valori di handle sono validi o meno per un determinato set di API.

+0

OK, forse, ma come mai non esiste una classe 'SafeHandleZeroIsInvalid'? Sicuramente ci sono * molte * API in più che restituiscono zero come valore non valido invece di -1? – Mehrdad

+1

Il problema chiave è che la stessa classe di handle deve funzionare con * entrambi * i tipi di API. "Zero * o * Meno uno" in questo caso significa che * entrambi * sono considerati non validi - non * o/o *. Ciò consente di utilizzare la stessa classe base con l'API CreateFile (restituisce INVALID_HANDLE_VALUE in caso di errore) come con CreateMutex (restituisce NULL in caso di errore). Perché due classi di base separate (che possono causare confusione ed errori se l'utente sceglie quella errata) quando è possibile gestire entrambi i casi? – BrendanMcK