1

D'après MSDN le handle
C'est un moyen d'acceder à un objet managé à partir d'une mémoire non managée.
OK, mais j'ai rien pigé, sauf peut être dans le cas d'un wrapper obtenir le je-ne-sais-quoi (adresse/pointeur ou objet/classe/mémoire) qui vient du C++ par exemple. Mais dans la définition, rien ne dit tout cela, ni si ça passe par com-interrop ou je ne sais quoi d’ailleurs.
C'est quoi un "handle" en managé, et en non managé ?
Qui pourrait m'expliquer svp?

2

Je pourrais.
Mais d'une part, ta question ne veut rien dire, ce qui montre en effet que t'as pas compris comment ça marche, mais ça montre aussi que t'as pas compris à quoi ça sert.
D'autre part, la documentation (même la version traduite en français) est limpide, et je ne vois pas ce qu'il y aurait de mieux à faire que la paraphraser…
GCHandle, structure; Notes :
La classe GCHandle est utilisée avec l'énumération GCHandleType pour créer un handle correspondant à n'importe quel objet managé. Il existe quatre types possibles pour ce handle : Weak, WeakTrackResurrection, Normal ou Pinned. Lorsque le handle a été affecté, vous pouvez l'utiliser pour empêcher l'objet managé d'être récupéré par le garbage collector lorsqu'un client non managé détient la seule référence. Sans un tel handle, l'objet peut être récupéré par le garbage collector avant d'avoir terminé l'action qu'il est en train d'accomplir pour le client non managé.

Vous pouvez également utiliser GCHandle pour créer un objet épinglé qui retourne une adresse mémoire et empêche le garbage collector de placer l'objet en mémoire.
Lorsque le handle est hors de portée, vous devez le libérer explicitement en appelant la méthode Free ; sinon, des fuites de mémoire peuvent se produire. Lorsque vous libérez un handle épinglé, l'objet associé est désépinglé et devient disponible pour le garbage collection s'il n'y a pas d'autres références à celui-ci.

Deux des utilisations possibles sont mentionnées là dedans… Si tu ne comprends pas, c'est certainement que tu ne comprends pas la gestion de la mémoire par .NET, donc creuse d'abord de ce côté…
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

3

L'autre problème, c'est "l'ancien" sens du mot "handle". En fait, il n'y a pas assez de mots différents pour qualifier:
* Les pointeurs de base ("pointeur")
* Les références C++ ("référence")
* Les "références d'objet" indiquant un objet managé ("handle" en C++/CLI, "référence" pour la plupart des autres langages): En gros, si tu as programmé en Java, ça correspond tout simplement à une référence Java
* Les "fichiers ouverts" vus de Windows et divers autres choses de l'API Windows ("handle" aussi).
Des classes comme GCHandle désignent le sens rouge du terme.
Des classes comme SafeHandle désignent le sens bleu du terme.

GCHandle(Pinned) permet d'obtenir un "pointeur punaise" sur un objet managé, via sa méthode AddrOfPinnedObject(). C'est l'équivalent du pin_ptr<> de C++/CLI.
GCHandle(Normal) permet de stocker une référence d'objet managé dans un contexte non-managé, ce doit être assez voisin du gcroot<> de C++/CLI.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

4

Mais non, n'embrouille pas les choses tongue
Tout simplement un handle, c'est juste un objet (au sens langage courant, pas C/C++ hein…) qui en représente un autre, d'une manière que tu n'a pas à connaître.
À en juger par le nom, tu peux deviner qu'on a appelé ça comme ça (handle, « poignée ») parce qu'une poignée te permet de t'accrocher à l'objet sans le toucher directement, et c'est exactement ce que ça fait dans la manière dont on s'en sert.
Tous les handle sont bien des handle, chacun au même titre que les autres
Un pointeur peut bien être un handle, mais si tu sais que c'est un pointeur alors c'est un mauvais handle. Une grande partie de l'utilité d'un handle implique une opacité de ce qui est derrière ainsi que de la méthode employée pour ce faire.
Un handle peut être implémenté par un pointeur, un index dans un tableau, ou bien même par un numéro totalement aléatoire qui va indexer une entrée dans une table de hachage, mais ça ne te regarde pas plus que ce qu'il cache derrière.
Il y a des handle (par exemple en API WIn32) dont le fonctionnement interne a été dévoilé (HMODULE ou HINSTANCE par exemple) mais ça ne veut pas dire que tu dois utiliser ces connaissances dans ton programme, ni que ces informations resteront vraie tout le temps.
Et il y a une règle implicite qui est que si tu violes la règle de l'opacité, alors tu n'a aucune garantie que ton code fonctionne sur toutes les versions futures (ou même passées) du produit que tu vises. Bref, c'est mal, et c'est crade ! Un handle c'est juste un handle et rien d'autre smile

PS: T'as oublié Weak et WeakTrackResurrection tongue
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

5

GoldenCrystal (./4) :
Un pointeur peut bien être un handle, mais si tu sais que c'est un pointeur alors c'est un mauvais handle. Une grande partie de l'utilité d'un handle implique une opacité de ce qui est derrière ainsi que de la méthode employée pour ce faire.

C'est pas toi qui me disait que l'héritage sapue ? Parce que là c'est bien de ça qu'il est question non, tous les objets que tu crées héritent de Handle pour accéder à certains types de manipulation ou à peu près, non ?

6

Folco (./5) :
Parce que là c'est bien de ça qu'il est question non, tous les objets que tu crées héritent de Handle pour accéder à certains types de manipulation ou à peu près, non ?
Heu, non cheeky
Un handle c'est pas un objet au sens C++, Java ou C#. Pas un truc dont tu peux hériter. C'est juste un handle.
Après tu peux concevoir *tes* propres handles pour qu'ils suivent une hiérarchie (c'est le cas avec certaines APi Win32). Par exemple les fonctions qui travaillent sur des handles de types HFRUIT (représentant le type interne Fruit) accepteront aussi les handles de type HBANANE (représentant le type interne Banane, dérivé de Fruit).
Y'a aucune fonction universellement apellable sur un HANDLE, c'est juste un concept abstrait, au même titre qu'un objet (tu as plusieurs façons de concevoir les objets, pas forcément compatibles entre elles), après tu l'implémentes un peu comme tu veux tant que tu respectes les règles, mais ça ne sera jamais compatible avec les autres (ou alors par pur hasard).
En fait la seule chose que les handle ont en commun c'est d'être représentés par des valeurs qui sont en général des entiers de la taille d'un pointeur natif, ou bien directement des pointeurs (cela revient plus ou moins au même en principe). Parce que peu importe les chemins que tu empruntes, un objet finit toujours par se résumer à un chiffre quelque part… winket
C'est pas toi qui me disait que l'héritage sapue ?
trifus
Je sais pas ce que j'ai pu te dire mais certainement pas ça. grin
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

7

Un handle est-il "une sorte de pointeur" vers un "objet", de n'importe quel type : pointeur, classe, etc , ou bien une "sorte d'objet" vers ... un pointeur triso, ou autre chose ?

Quel est son intérêt face à un pointeur, mis à part de l'épargner du garbage collector lorsqu'il est Pinned ?

8

Comprend d'abord ce qu'est un handle tongue
Dans le cas de GCHandle c'est simple, un GCHandle est aussi un IntPtr (enfin plus ou moins à « quelques » détails près), comme tous les handle.
Et un GCHandle représente un objet CLR. Représente pas pointe, ni référence !
Comme tous les handle il peut être obtenu en sortie d'une fonction qui retourne ce type de handle, et passé en entrée d'une fonction qui accepte ce type de handle.
Les propriétés (Weak, WeakTraceResurrection, Normal et Pinned) affectées au GCHandle lors de sa création sont spécifiques à la gestion de mémoire de .NET, si tu ne comprends pas ces principes je te suggère de creuser de ce côté. (bis)
C'est une fonctionnalité assez bas niveau de l'environnement .NET, utile dans un nombre réduit de cas, et seulement si tu comprends la gestion mémoire ainsi que les problématiques qui lui sont associées.
De plus un exemple d'utilisation typique est fourni dans la documentation MSDN (bis) étudie-le, jusqu'à ce que tu le comprennes.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

9

GoldenCrystal (./6) :
Y'a aucune fonction universellement apellable sur un HANDLE

Ta phrase aurait été vraie si tu n'avais pas commis l'erreur de mettre "HANDLE" en majuscule: Sous Windows, HANDLE a une signification particulière, qui est "Handle vers un objet du Kernel" (fichier ouvert, mutex, etc.)

En .Net on tend à s'en moquer un peu, mais on a un autre problème: La documentation C++/CLI qui appelle "handle" les fameux "pointeurs managés"/"références java" etc. Les valeurs retournées par la classe GCHandle sont proches de ceci, mais ne sont pas des handles: Plusieurs GCHandle(Normal) sur un même objet auront des valeurs différentes.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

10

Link (./9) :
GoldenCrystal (./6) :
Y'a aucune fonction universellement apellable sur un HANDLE

Ta phrase aurait été vraie si tu n'avais pas commis l'erreur de mettre "HANDLE" en majuscule: Sous Windows, HANDLE a une signification particulière, qui est "Handle vers un objet du Kernel" (fichier ouvert, mutex, etc.)
Alors parce que je met des majuscules la phrase devient fausse ? triso
D'une part Windows n'est pas nécessairement la seule API à définir HANDLE en majuscules (même si c'est vrai que c'est à cause de ça que je l'ai écrit, par habitude), et d'autre part ce que tu dis est faux wink
Le HANDLE défini par les header Win32 est une définition générique d'un handle, et ça n'a aucune implication quand à l'implémentation interne de ce handle. Tu as du confondre avec le fait que les fonctions qui prennent une valeur Win32 HANDLE brute ne concernent que les HANDLE gérés par le noyau, dont les types sont plus ou moins bien documentés (il y en a peut-être certains cachés, je sais plus)
(PS: avant de me répondre, regarde uxtheme.h)
Plusieurs GCHandle(Normal) sur un même objet auront des valeurs différentes.
D'une part c'est tout à fait logique et normal, d'autre part je vois pas où tu veux en venir ?
T'as deux handle qui représentent le même objet, et ? Ça ne change pas leurs propriétés. cheeky
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

11

GoldenCrystal (./10) :
Plusieurs GCHandle(Normal) sur un même objet auront des valeurs différentes.
D'une part c'est tout à fait logique et normal, d'autre part je vois pas où tu veux en venir ?
T'as deux handle qui représentent le même objet, et ? Ça ne change pas leurs propriétés. cheeky

Cette partie-là, elle allait dans ton sens: Un GCHandle n'est pas un "pointeur managé", comme tu le disais.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

12

Le HANDLE défini par les header Win32 est une définition générique d'un handle, et ça n'a aucune implication quand à l'implémentation interne de ce handle. Tu as du confondre avec le fait que les fonctions qui prennent une valeur Win32 HANDLE brute ne concernent que les HANDLE gérés par le noyau, dont les types sont plus ou moins bien documentés (il y en a peut-être certains cachés, je sais plus) (PS: avant de me répondre, regarde uxtheme.h)

Dans les conventions de nommage de Windows, les handles vers autre chose que les objets du noyau ont chacun leur propre typedef HTRUC. Les fonctions où Windows utilise HANDLE de manière générique sont rares; de mémoire, je ne connais que LoadImage().
Dans uxtheme.h, je n'ai vu que des HTHEME, ce qui suit ce que je dis.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

13

Il en reste que tous les HMACHIN sont des HANDLE, mêmes ceux qui ne sont pas gérés par le noyau tongue
(Et j'ai choisi uxtheme pour ça, car en plus de la relative évidence de la chose, j'ai pu le vérifier par moi même quand j'ai reverse-engineer certains API privées qui du coup ont été utilises par pas mal de monde après tongue)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

14

Des HANDLE, ou des handles?

Je sais qu'il y a toujours des différences entre les HANDLE kernel, les handles User et les handles GDI: Les premiers sont duplicables et permettent de partager un objet d'un processus à l'autre, les seconds sont valides partout, et les derniers indiquent des objets purement locaux... Voudrais-tu dire que sous le capot, ils sont tous dans le même espace?
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

15

Ce que je voulais dire, c'est que sous le capot, #define DECLARE_HANDLE(name) typedef HANDLE name(Désolé j'avais pas accès aux header Win32 quand j'ai lu ton post hier, et j'ai oublié entre temps tongue)
Ceci est la définition normale, lorsque le mode STRICT (qui t'empêche de mélanger les différents types de HANDLE entre eux) est désactivé, ce qui n'est pas le cas par défaut sous Visual Studio.
Et puis, ce que je voulais vraiment dire c'est ça:
MSDN :
the generic HANDLE type
:] (le soulignement est de moi)
(Je savais bien que je finirai par trouver une page de la documentation qui en parlait plus explicitement ! tongue)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

16

Je ne sais pas d'où tu sors cette déclaration, mais elle est fausse: C'est en réalité un truc de ce genre (de mémoire):
#define DECLARE_HANDLE(x) typedef struct x ## __ *x
C'est ce qui fait qu'un HWND possède en réalité le type struct HWND__ * sous Visual.

De plus, je sais de source sûre que les HWND n'utilisent pas le même namespace que les HANDLE, car bien qu'apparemment forcément pairs, les HWNDs ne sont pas forcément multiples de 4, ce qui est exigé des HANDLE.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

17

La déclaration entière c'est ça #ifdef STRICT typedef void *HANDLE; #if 0 && (_MSC_VER > 1000) #define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name #else #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name #endif #else typedef PVOID HANDLE; #define DECLARE_HANDLE(name) typedef HANDLE name #endif typedef HANDLE *PHANDLE; smile (On ignorera bien entendu le bloc #if 0…)
En standard, tout handle était affectable à tout autre handle. Et tous les handles sont dérivés de HANDLE. (Normal, c'est le même concept de type opaque tongue)
Ce qui a évidemment pu inciter les mauvais développeur à les mélanger dans leurs utilisation.
C'est le mode strict qui rend la plupart des types incomaptibles entre eux. La multiplicité « exigée » n'a pas rapport avec le type HANDLE, c'est juste un détail d'implémentation des HANDLE gérés par le noyau, qui a été documenté par Microsoft. (Et ça peut pas être « exigé » vu que ce n'est aps toi qui les crées mais c'est le système qui te les fournit…)
Le fait qu'il soit documenté implique que du coup tu peux t'en servir si tu sais ce que tu fais, mais bon, mieux vaut éviter malgré tout… tongue
Pour te citer un de mes blog favoris:
The availability of the bottom two bits is buried in the ntdef.h header file:

//
// Low order two bits of a handle are ignored by the system and available
// for use by application code as tag bits. The remaining bits are opaque
// and used to store a serial number and table index.
//
#define OBJ_HANDLE_TAGBITS 0x00000003L

(Et puis dans uxtheme c'est bien un bête typedef HANDLE wink )
Tu semble comparer les handle par leur implémentation (multiple de 2 / 4) alors que ce qui compte c'est uniquement le concept tongue

Enfin bref grin
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

18

Mais là, on a déjà mélangé niveau conceptuel et implémentation: Au niveau conceptuel, il n'y a pas de "HANDLE", seulement des handles.

Le fait que les handles soient répartis en différent types (HANDLE, Hxxxx) est déjà un détail d'implémentation. "HANDLE" est une implémentation.

Et si on parle d'implémentation, alors HANDLE est restreint aux objets du kernel, possédant un espace de valeurs par processus, restreint aux multiples de 4, tandis que HWND est un autre type, dans un espace de valeurs différent global au système (et sans doute partagé avec les autres types de handle User).
Comme je l'ai dit, dans l'implémentation, HANDLE n'est pratiquement jamais utilisé de manière générique, à part dans LoadImage() et donc apparemment dans uxtheme.

Par contre, le concept de handle est parfaitement générique et universel. Mais HANDLE n'est pas un concept.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.