Cos'è un handle in C ++?


97

Mi è stato detto che un handle è una specie di puntatore, ma non lo è, e che ti permette di mantenere un riferimento a un oggetto, piuttosto che all'oggetto stesso. Qual è una spiegazione più elaborata?



2
Esamina il modello Catena di responsabilità, imparerai che un "Handle" è fondamentalmente un nodo e che un "Handler" è un piccolo insieme di essi. La "magia" viene dalla ricorsione

Risposte:


100

Un handle può essere qualsiasi cosa, da un indice intero a un puntatore a una risorsa nello spazio del kernel. L'idea è che forniscono un'astrazione di una risorsa, quindi non è necessario sapere molto sulla risorsa stessa per utilizzarla.

Ad esempio, l'HWND nell'API Win32 è un handle per una finestra. Di per sé è inutile: non puoi ricavarne alcuna informazione. Ma passalo alle funzioni API corrette e puoi eseguire una vasta gamma di trucchi diversi con esso. Internamente puoi pensare all'HWND come a un semplice indice nella tabella delle finestre della GUI (che potrebbe non essere necessariamente il modo in cui è implementato, ma ha senso la magia).

EDIT: Non è sicuro al 100% cosa stavi chiedendo nello specifico nella tua domanda. Si tratta principalmente di puro C / C ++.


13
Una maniglia può essere utile per salvare gli stati (tra gli altri). Se hai dati in una struttura come std :: vector. Il tuo oggetto potrebbe trovarsi in posizioni di memoria diverse in momenti diversi durante l'esecuzione di un programma, il che significa che il tuo puntatore a quella memoria cambierà i valori. Con una maniglia non cambia mai, fa sempre riferimento al tuo oggetto. Immagina di salvare lo stato di un programma (come in un gioco): non salveresti una posizione del puntatore nei dati e successivamente importeresti di nuovo i dati e proveresti a ottenere quell'indirizzo in memoria. È tuttavia possibile salvare un handle con i dati e importare i dati e l'handle.
SinisterRainbow

È possibile convertire un HANDLE in un equivalente in Linux? Devo migrare un programma che utilizza HANDLE da Windows a Linux.
Cornel Verster

1
Questa è la risposta corretta, che possono essere qualsiasi cosa e che il codice che li utilizza definisce il tipo di handle. Ho provato a fare una versione più concisa della mia risposta simile, non ho potuto farne a meno, per i posteri. @CornelVerster - Sono gli stessi in Linux. Voglio dire, non le maniglie del sistema operativo, ma il concetto. Quindi, dipende dalla maniglia per la sua migrazione, o anche dalla necessità di migrare.
dyasta

@Matthew Iselin: in qualsiasi documentazione API, definiscono che cosa è un gestore, allora dovremmo sapere di passarli alle funzioni, altrimenti come possiamo sapere cos'è un gestore nella documentazione API
Amin Khormaei

51

Un handle è un puntatore o un indice a cui non è associato alcun tipo visibile. Di solito vedi qualcosa come:

 typedef void* HANDLE;
 HANDLE myHandleToSomething = CreateSomething();

Quindi nel tuo codice devi solo passare HANDLE come un valore opaco.

Nel codice che utilizza l'oggetto, esegue il cast del puntatore a un tipo di struttura reale e lo utilizza:

 int doSomething(HANDLE s, int a, int b) {
     Something* something = reinterpret_cast<Something*>(s);
     return something->doit(a, b);
 }

Oppure lo usa come indice per un array / vettore:

 int doSomething(HANDLE s, int a, int b) {
     int index = (int)s;
     try {
         Something& something = vecSomething[index];
         return something.doit(a, b);
     } catch (boundscheck& e) {
         throw SomethingException(INVALID_HANDLE);
     }
 }

29

Un handle è una sorta di puntatore in quanto è tipicamente un modo per fare riferimento a un'entità.

Sarebbe più accurato dire che un puntatore è un tipo di handle, ma non tutti gli handle sono puntatori.

Ad esempio, un handle può anche essere un indice in una tabella in memoria, che corrisponde a una voce che a sua volta contiene un puntatore a un oggetto.

La cosa fondamentale è che quando hai una "maniglia", non sai né ti interessa come quella maniglia finisce effettivamente per identificare la cosa che identifica, tutto ciò che devi sapere è che lo fa.

Dovrebbe anche essere ovvio che non esiste un'unica risposta a "che cosa è esattamente una maniglia", perché le maniglie a cose diverse, anche nello stesso sistema, possono essere implementate in modi diversi "sotto il cofano". Ma non dovresti preoccuparti di queste differenze.


6

In C ++ / CLI, un handle è un puntatore a un oggetto situato nell'heap GC. La creazione di un oggetto sull'heap C ++ (non gestito) si ottiene utilizzando newe il risultato di newun'espressione è un puntatore "normale". Un oggetto gestito viene allocato sull'heap GC (gestito) con gcnewun'espressione. Il risultato sarà una maniglia. Non puoi eseguire operazioni aritmetiche con i puntatori sulle maniglie. Non liberi le maniglie. Il GC si prenderà cura di loro. Inoltre, il GC è libero di riposizionare gli oggetti sull'heap gestito e aggiornare gli handle in modo che puntino alle nuove posizioni mentre il programma è in esecuzione.


5

Questo appare nel contesto del linguaggio Handle-Body-Idiom , chiamato anche idioma Pimpl. Consente di mantenere invariata l'ABI (interfaccia binaria) di una libreria, mantenendo i dati effettivi in ​​un altro oggetto di classe, a cui fa semplicemente riferimento un puntatore tenuto in un oggetto "handle", costituito da funzioni che delegano a quella classe " Corpo".

È anche utile per abilitare il tempo costante e lo scambio sicuro rispetto alle eccezioni di due oggetti. Per questo, deve essere scambiato semplicemente il puntatore che punta all'oggetto del corpo.


2

Una maniglia è qualunque cosa tu voglia che sia.

Un handle può essere un numero intero senza segno utilizzato in alcune tabelle di ricerca.

Un handle può essere un puntatore a, o in, un set di dati più ampio.

Dipende da come si comporta il codice che utilizza l'handle. Questo determina il tipo di maniglia.

Ciò che è importante è il motivo per cui viene utilizzato il termine " maniglia ". Ciò li indica come identificazione o tipo di accesso dell'oggetto. Significa che per il programmatore rappresentano una "chiave" o l' accesso a qualcosa.


2

HANDLE hnd; equivale a void * ptr;

HANDLE è un typedef definito nel file winnt.h in Visual Studio (Windows):

typedef void *HANDLE;

Maggiori informazioni su HANDLE


1
Ciò vale solo per Windows e solo uno dei tanti tipi di handle utilizzati tramite l'architettura di Windows. Tuttavia, questo è ciò che sarebbe noto come un "normale handle a livello di applicazione di Windows".
dyasta
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.