Puis-je utiliser SafeHandle au lieu de IntPtr?
J'ai cherché sur internet et au loin, mais n'ai pas trouvé une bonne explication.
Ma question est assez simple.
J'ai une DLL qui a une fonction appelée Initialiser et l'un des paramètres est un pointeur qui recevra une poignée pour être utilisé avec des appels ultérieurs. Un autre paramètre est une chaîne que je vais pour l'exhaustivité. La signature que j'utilise est (dans sa forme simple):
[DllImport(MyDll)]
static extern bool Initialize([In] string name, out IntPtr handle);
De la signature, à la DLL est lui-même écrit que: Initialize(LPTSTR name, HANDLE handle)
avec le commentaire "de la POIGNÉE: Pointeur vers un emplacement qui permettra de recevoir la poignée".
Et les appels suivants sont sous la forme de
[DllImport(MyDll)]
static extern bool DoSomething(IntPtr handle, uint randomParameter);
J'ai lu sur SafeHandle
et je me demandais si je pouvais l'utiliser pour substite pour mon IntPtr poignée. Et si je peux, comment dois-je faire? L'extension de l'abstrait SafeHandle classe n'est pas un problème, mais ce que je peux directement remplacer mon IntPtr pour SafeHandle (et utiliser la valeur par défaut de Triage), ou dois-je faire quelque chose?
SafeHandle
vous donner juste le stockage de l' IntPtr
ne l'est pas?SafeHandle
est IDisposable
et s'assure que les ressources visées par la poignée sont libérés. IntPtr
est simplement un pointeur de la taille d'une valeur qui ne peut être passée autour d' - il n'a pas l'élimination de la sémantique.En supposant que vous êtes autorisé à des frais de la mémoire, à moins que vous pouvez affecter le pointeur de la mémoire à l'aide de
Marshal.FreeBSTR
, Marshal.FreeCoTaskMem
, ou Marshal.FreeHGlobal
, je ne pense pas que vous pouvez en toute sécurité de-allouer de la mémoire à partir de C#. À l'aide de IntPtr
, C# ne pas tenter de libérer la mémoire automatiquement.OriginalL'auteur Davio | 2012-08-15
Vous devez vous connecter pour publier un commentaire.
Vous pouvez trouver une réponse plus complète à propos de la différence entre
SafeHandle
etIntPtr
ici: IntPtr, SafeHandle et HandleRef - ExpliquéToutefois, pour résumer,
IntPtr
doit être utilisé lorsque l'argument est en fait un machine-taille du pointeur de la -SafeHandle
doit être utilisé lorsque l'argument est en fait un handle Win32. Ces types ne sont généralement pas interchangeables; la taille deIntPtr
varie sur des architectures différentes (32 bits x86 ou 64 bits x64 et amd64). REMARQUE: Sous les couvertures, je croisSafeHandle
utilise unIntPtr
).Aussi, contrairement à
IntPtr
,SafeHandle
procède effectivement à disposition de ressources lorsqu'un type est des ordures collectées. Cela garantit que les ressources système sont pas de fuite lorsque votre programme est en cours d'exécution (bien que vous devriezDispose()
deSafeHandle
cas au début quand c'est possible). Notez queSafeHandle
est en réalité abstraite car il y a beaucoup de différents types de poignées qui nécessitent des approches différentes pour une bonne élimination et de manipulation.Dans votre cas particulier, vous avez besoin de regarder la documentation de la DLL que vous appelez. Si c'est une DLL Win32, il y a peut-être déjà un SafeHandle type. Si c'est une DLL de tiers, alors vous pouvez rouler vos propres SafeHandle mise en œuvre - en supposant que, en plus de
Initialize()
il y a une version deRelease()
(ou l'équivalent).Quelques autres détails intéressants à propos de IntPtr vs SafeHandle peut être trouvé à:
Utilisation SafeHandle pour encapsuler des ressources natives
SafeHandle De Référence De Classe
SafeHandles de la Critique et de la Finalisation de la
IntPtr
est de 64 bits pas de 65 ans? J'ai fait l'édition-s'il vous plaît revenir et expliquer plus (je suis prêt pour cela à mon "apprendre quelque chose de nouveau chaque jour moment).Ainsi, la création de mon propre SafeHandle implentation comme je l'ai dit, c'est pas une grosse affaire, il y a beaucoup d'exemples sur elle. Ce que je voudrais savoir c'est si je peux utiliser SafeHandle et IntPtr interchangeables, donc je pourrais faire:
static extern bool Initialize([In] string name, out SafeHandle)
au lieu de l'actuellestatic extern bool Initialize([In] string name, out IntPtr)
?Non, c'était juste une faute de frappe de ma part. Merci pour l'attraper.
En principe, vous devriez être en mesure d'utiliser votre personnalisé
SafeHandle
-dérivés à la place deIntPtr
. L'interop marshaling système a une manipulation spéciale pourSafeHandles
. Cependant, l'écriture d'une mise en œuvre correctement la poignée de la classe qui nécessite des soins. Lire la section "remarques" dans SafeHandle Classe de Référence comme un point de départ.OriginalL'auteur LBushkin