Was ist ein Handle in C ++?

97

Mir wurde gesagt, dass ein Handle eine Art Zeiger ist, aber nicht, und dass Sie damit einen Verweis auf ein Objekt und nicht auf das Objekt selbst behalten können. Was ist eine ausführlichere Erklärung?

Xenoprimate
quelle
2
Wenn Sie sich das Muster der Verantwortungskette ansehen, werden Sie feststellen, dass ein "Handle" im Grunde ein Knoten ist und dass ein "Handler" eine kleine Menge davon ist. Die "Magie" kommt von der Rekursion

Antworten:

100

Ein Handle kann alles sein, von einem Ganzzahlindex bis zu einem Zeiger auf eine Ressource im Kernelraum. Die Idee ist, dass sie eine Abstraktion einer Ressource bereitstellen, sodass Sie nicht viel über die Ressource selbst wissen müssen, um sie zu verwenden.

Beispielsweise ist der HWND in der Win32-API ein Handle für ein Fenster. An sich ist es nutzlos: Sie können keine Informationen daraus gewinnen. Übergeben Sie es jedoch an die richtigen API-Funktionen, und Sie können damit eine Vielzahl verschiedener Tricks ausführen. Intern können Sie sich den HWND nur als einen Index in der Fenstertabelle der GUI vorstellen (was möglicherweise nicht unbedingt so ist, wie er implementiert ist, aber die Magie macht Sinn).

EDIT: Nicht 100% sicher, was genau Sie in Ihrer Frage gefragt haben. Hier geht es hauptsächlich um reines C / C ++.

Matthew Iselin
quelle
13
Ein Handle kann (unter anderem) zum Speichern von Status nützlich sein. Wenn Sie Daten in einer Struktur wie einem std :: vector haben. Ihr Objekt befindet sich möglicherweise zu unterschiedlichen Zeiten während der Ausführung eines Programms an verschiedenen Speicherorten. Dies bedeutet, dass Ihr Zeiger auf diesen Speicher die Werte ändert. Mit einem Handle ändert es sich nie, es verweist immer auf Ihr Objekt. Stellen Sie sich vor, Sie speichern einen Programmstatus (wie in einem Spiel) - Sie würden keinen Zeiger auf Daten speichern und die Daten später erneut importieren und versuchen, diese Adresse im Speicher abzurufen. Sie können jedoch ein Handle mit Ihren Daten speichern und die Daten und das Handle importieren.
SinisterRainbow
Ist es möglich, einen HANDLE unter Linux in ein Äquivalent umzuwandeln? Ich muss ein Programm migrieren, das HANDLE von Windows auf Linux verwendet.
Cornel Verster
1
Das ist die richtige Antwort, dass sie alles sein können und dass der Code, der sie verwendet, den Typ des Handles definiert. Ich habe versucht, eine präzisere Version meiner eigenen ähnlichen Antwort zu erstellen, konnte mir aber nicht helfen, für die Nachwelt. @CornelVerster - Sie sind die gleichen unter Linux. Ich meine, nicht OS-Handles, sondern das Konzept. Es hängt also vom Handle hinsichtlich der Migration ab oder muss sogar migriert werden.
Dyasta
@Matthew Iselin: Definieren sie in einer API-Dokumentation, dass es sich bei diesem Objekt um einen Handler handelt, dann sollten wir wissen, dass wir sie an Funktionen übergeben müssen. Andernfalls können wir wissen, was ein Handler in der API-Dokumentation ist
Amin Khormaei,
51

Ein Handle ist ein Zeiger oder Index, an den kein sichtbarer Typ angehängt ist. Normalerweise sehen Sie so etwas wie:

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

In Ihrem Code geben Sie HANDLE einfach als undurchsichtigen Wert weiter.

In dem Code, der das Objekt verwendet, wird der Zeiger auf einen realen Strukturtyp umgewandelt und verwendet:

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

Oder es verwendet es als Index für ein Array / einen Vektor:

 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);
     }
 }
jmucchiello
quelle
29

Ein Handle ist insofern eine Art Zeiger, als es normalerweise eine Art ist, auf eine Entität zu verweisen.

Es wäre genauer zu sagen, dass ein Zeiger eine Art von Handle ist, aber nicht alle Handles sind Zeiger.

Beispielsweise kann ein Handle auch ein Index in einer In-Memory-Tabelle sein, der einem Eintrag entspricht, der selbst einen Zeiger auf ein Objekt enthält.

Das Wichtigste ist, dass Sie, wenn Sie ein "Handle" haben, weder wissen noch sich darum kümmern, wie dieses Handle das identifizierte Objekt identifiziert. Alles, was Sie wissen müssen, ist, dass es das tut.

Es sollte auch offensichtlich sein, dass es keine einheitliche Antwort auf "Was genau ist ein Handle" gibt, da Handles für verschiedene Dinge, selbst im selben System, auf unterschiedliche Weise "unter der Haube" implementiert werden können. Aber Sie sollten sich nicht mit diesen Unterschieden befassen müssen.

Deltics
quelle
6

In C ++ / CLI ist ein Handle ein Zeiger auf ein Objekt auf dem GC-Heap. Das Erstellen eines Objekts auf dem (nicht verwalteten) C ++ - Heap erfolgt mithilfe von newund das Ergebnis eines newAusdrucks ist ein "normaler" Zeiger. Ein verwaltetes Objekt wird auf dem GC-Heap (verwaltet) mit einem gcnewAusdruck zugewiesen . Das Ergebnis wird ein Handle sein. Sie können keine Zeigerarithmetik für Ziehpunkte ausführen. Sie geben keine Griffe frei. Der GC wird sich um sie kümmern. Außerdem kann der GC Objekte auf dem verwalteten Heap verschieben und die Handles aktualisieren, um auf die neuen Speicherorte zu verweisen, während das Programm ausgeführt wird.

Mehrdad Afshari
quelle
5

Dies erscheint im Kontext des Handle-Body- Idioms, auch Pimpl-Idiom genannt. Es ermöglicht, die ABI (binäre Schnittstelle) einer Bibliothek gleich zu halten, indem die tatsächlichen Daten in einem anderen Klassenobjekt gespeichert werden, auf das lediglich durch einen Zeiger verwiesen wird, der in einem "Handle" -Objekt enthalten ist, das aus Funktionen besteht, die an diese Klasse delegieren. " Körper".

Es ist auch nützlich, einen konstanten zeit- und ausnahmesicheren Austausch zweier Objekte zu ermöglichen. Dazu muss lediglich der Zeiger auf das Körperobjekt getauscht werden.

Johannes Schaub - litb
quelle
2

Ein Griff ist das, was Sie wollen.

Ein Handle kann eine vorzeichenlose Ganzzahl sein, die in einer Nachschlagetabelle verwendet wird.

Ein Handle kann ein Zeiger auf oder in einen größeren Datensatz sein.

Dies hängt davon ab, wie sich der Code, der das Handle verwendet, verhält. Das bestimmt den Handle-Typ.

Der Grund, warum der Begriff " Handle " verwendet wird, ist wichtig. Dies zeigt sie als Identifikations- oder Zugriffstyp eines Objekts an. Für den Programmierer bedeutet dies, dass sie einen „Schlüssel“ oder Zugriff auf etwas darstellen.

Dyasta
quelle
2

HANDLE hnd; ist das gleiche wie void * ptr;

HANDLE ist ein typedef, der in der Datei winnt.h in Visual Studio (Windows) definiert ist:

typedef void *HANDLE;

Lesen Sie mehr über GRIFF

Kulamani
quelle
1
Dies gilt nur für Windows und nur für eine von vielen Arten von Handles, die in der Windows-Architektur verwendet werden. Dies wird jedoch als "normales Handle auf Windows-Anwendungsebene" bezeichnet.
Dyasta