Qu'est-ce qu'un handle en C ++?

97

On m'a dit qu'une poignée est une sorte de pointeur, mais pas, et qu'elle permet de conserver une référence à un objet, plutôt qu'à l'objet lui-même. Qu'est-ce qu'une explication plus élaborée?

Xénoprimate
la source
2
Examinez le modèle de chaîne de responsabilité, vous apprendrez qu'un «handle» est essentiellement un nœud, et qu'un «gestionnaire» est un petit ensemble d'entre eux. La "magie" vient de la récursion

Réponses:

100

Un handle peut être n'importe quoi, d'un index entier à un pointeur vers une ressource dans l'espace noyau. L'idée est qu'ils fournissent une abstraction d'une ressource, vous n'avez donc pas besoin d'en savoir beaucoup sur la ressource elle-même pour l'utiliser.

Par exemple, le HWND dans l'API Win32 est un handle pour une fenêtre. En soi, c'est inutile: vous ne pouvez en tirer aucune information. Mais transmettez-le aux bonnes fonctions de l'API, et vous pouvez effectuer une multitude d'astuces différentes avec. En interne, vous pouvez considérer le HWND comme un simple index dans la table des fenêtres de l'interface graphique (ce qui n'est peut-être pas nécessairement la manière dont il est implémenté, mais cela a du sens).

EDIT: Pas sûr à 100% de ce que vous demandiez précisément dans votre question. Il s'agit principalement de C / C ++ pur.

Matthieu Iselin
la source
13
Un handle peut être utile pour enregistrer des états (entre autres). Si vous avez des données dans une structure comme un std :: vector. Votre objet peut se trouver à différents emplacements de mémoire à différents moments pendant l'exécution d'un programme, ce qui signifie que votre pointeur vers cette mémoire changera de valeur. Avec une poignée, il ne change jamais, il fait toujours référence à votre objet. Imaginez que vous enregistrez l'état d'un programme (comme dans un jeu) - vous ne sauvegarderiez pas l'emplacement du pointeur vers les données, vous importeriez à nouveau les données et n'essaieriez pas d'obtenir cette adresse en mémoire. Vous pouvez cependant enregistrer un handle avec vos données et importer les données et le handle.
SinisterRainbow
Est-il possible de convertir un HANDLE en un équivalent sous Linux? Je dois migrer un programme qui utilise HANDLE de Windows vers Linux.
Cornel Verster
1
C'est la bonne réponse, qu'ils peuvent être n'importe quoi et que le code qui les utilise définit le type de handle. J'ai essayé de faire une version plus concise de ma propre réponse similaire, je n'ai pas pu m'en empêcher, pour la postérité. @CornelVerster - Ils sont les mêmes sous Linux. Je veux dire, pas les poignées OS, mais le concept. Ainsi, cela dépend du handle quant à sa migration, voire de la nécessité de migrer.
dyasta
@Matthew Iselin: dans n'importe quelle documentation d'API, définissent-ils que cette chose est un gestionnaire alors nous devrions savoir comment les passer aux fonctions, sinon comment nous pouvons savoir ce qu'est un gestionnaire dans la documentation de l'API
Amin Khormaei
51

Un handle est un pointeur ou un index auquel aucun type visible n'est attaché. Habituellement, vous voyez quelque chose comme:

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

Donc, dans votre code, vous passez simplement HANDLE comme valeur opaque.

Dans le code qui utilise l'objet, il jette le pointeur sur un type de structure réel et l'utilise:

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

Ou il l'utilise comme index d'un tableau / vecteur:

 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
la source
29

Un handle est une sorte de pointeur en ce sens qu'il s'agit généralement d'un moyen de référencer une entité.

Il serait plus précis de dire qu'un pointeur est un type de poignée, mais que toutes les poignées ne sont pas des pointeurs.

Par exemple, un handle peut également être un index dans une table en mémoire, qui correspond à une entrée qui contient elle-même un pointeur vers un objet.

L'essentiel est que lorsque vous avez une «poignée», vous ne savez pas et ne vous souciez pas de la façon dont cette poignée finit par identifier la chose qu'elle identifie, tout ce que vous devez savoir, c'est qu'elle le fait.

Il devrait également être évident qu'il n'y a pas de réponse unique à «ce qu'est exactement une poignée», car les poignées de différentes choses, même dans le même système, peuvent être implémentées de différentes manières «sous le capot». Mais vous ne devriez pas avoir à vous soucier de ces différences.

Deltiques
la source
6

En C ++ / CLI, un handle est un pointeur vers un objet situé sur le tas GC. La création d'un objet sur le tas C ++ (non géré) est réalisée à l'aide de newet le résultat d'une newexpression est un pointeur "normal". Un objet géré est alloué sur le tas GC (géré) avec une gcnewexpression. Le résultat sera une poignée. Vous ne pouvez pas faire d'arithmétique de pointeur sur les poignées. Vous ne libérez pas de poignées. Le GC s'en chargera. En outre, le GC est libre de déplacer des objets sur le tas géré et de mettre à jour les poignées pour pointer vers les nouveaux emplacements pendant l'exécution du programme.

Mehrdad Afshari
la source
5

Cela apparaît dans le contexte de l' idiome Handle-Body-Idiom , également appelé idiome Pimpl. Il permet de conserver l'ABI (interface binaire) d'une bibliothèque identique, en conservant les données réelles dans un autre objet de classe, qui est simplement référencé par un pointeur contenu dans un objet "handle", composé de fonctions qui délèguent à cette classe " Corps".

Il est également utile d'activer le temps constant et l'échange sécurisé de deux objets. Pour cela, il suffit de permuter le pointeur pointant vers l'objet corps.

Johannes Schaub - litb
la source
2

Une poignée est ce que vous voulez qu'elle soit.

Un handle peut être un entier non signé utilisé dans une table de recherche.

Un handle peut être un pointeur vers, ou dans, un plus grand ensemble de données.

Cela dépend du comportement du code qui utilise le handle. Cela détermine le type de poignée.

La raison pour laquelle le terme « poignée » est utilisé est ce qui est important. Cela les indique comme un type d'objet d'identification ou d'accès. Ce qui signifie, pour le programmeur, ils représentent une «clé» ou un accès à quelque chose.

Dyasta
la source
2

HANDLE hnd; est le même que void * ptr;

HANDLE est un typedef défini dans le fichier winnt.h dans Visual Studio (Windows):

typedef void *HANDLE;

En savoir plus sur HANDLE

Kulamani
la source
1
Cela ne s'applique qu'à Windows et à l'un des nombreux types de descripteurs utilisés dans l'architecture Windows. Cependant, c'est ce que l' on appelle une «poignée de niveau de l' application normale de Windows.
dyasta