Kann ich mithilfe von SafeHandle-statt IntPtr?
Ich habe im internet gesucht weit und breit, aber nicht finden, eine gute Erklärung.
Meine Frage ist ziemlich einfach.
Ich habe eine DLL, die hat eine Funktion namens Initialize, und einer der Parameter ist ein Zeiger, erhalten ein handle verwendet werden, mit nachfolgenden Aufrufe. Ein weiterer parameter ist eine Zeichenkette, die ich Liste auf Vollständigkeit. Die Signatur, die ich verwende, ist (in seiner einfachen form):
[DllImport(MyDll)]
static extern bool Initialize([In] string name, out IntPtr handle);
Die Signatur der DLL selbst geschrieben: Initialize(LPTSTR name, HANDLE handle)
mit dem Kommentar "GRIFF: Zeiger auf einen Speicherort, erhalten Sie den Griff".
Und nachfolgende Aufrufe werden in form von
[DllImport(MyDll)]
static extern bool DoSomething(IntPtr handle, uint randomParameter);
Habe ich gelesen, über SafeHandle
und ich Frage mich, ob ich verwenden könnte, es zu substite für meine IntPtr handle. Und wenn ich kann, wie mache ich es? Verlängerung der abstract SafeHandle-Klasse ist nicht ein Problem, aber kann ich direkt Ersatz meine IntPtr für SafeHandle (und verwenden Sie die Standard-Marshalling) oder muss ich etwas extra zu tun?
SafeHandle
geben Sie, dass nur die Speicherung der IntPtr
nicht?SafeHandle
ist IDisposable
und sorgt dafür, dass Ressourcen bezeichnet, die durch das handle freigegeben werden. IntPtr
ist einfach ein Zeiger-große Wert, der übergeben werden kann, um, es hat keine Entsorgung Semantik.Angenommen, Sie sind erlaubt Gebühr für den Speicher, es sei denn, Sie können de-allocate der Zeiger Speicher mit
Marshal.FreeBSTR
, Marshal.FreeCoTaskMem
oder Marshal.FreeHGlobal
ich glaube nicht, dass Sie können sicher de-den Speicher von C#. Mit IntPtr
C# wird nicht versuchen, um den freien Speicher automatisch.InformationsquelleAutor Davio | 2012-08-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Finden Sie eine vollständige Antwort über den Unterschied zwischen
SafeHandle
undIntPtr
hier: IntPtr, SafeHandle-und HandleRef, ErklärteAber, um es zusammenzufassen,
IntPtr
sollte verwendet werden, wo das argument ist eigentlich ein Maschine-Größe Zeiger -SafeHandle
sollte verwendet werden, wo das argument ist eigentlich ein Win32-handle. Diese Arten sind in der Regel nicht austauschbar; die GrößeIntPtr
variieren in verschiedenen Architekturen (32-bit auf x86 und 64 bit auf 64 bit) und amd64). HINWEIS: Unter der Decke, ich glaubeSafeHandle
verwendet eineIntPtr
).Auch, im Gegensatz zu
IntPtr
,SafeHandle
tatsächlich führt die Entsorgung von Ressourcen, wenn eine Art garbage Collection. Dies stellt sicher, dass system-Ressourcen sind nicht durchgesickert, wenn Ihr Programm ausgeführt wird (obwohl Sie solltenDispose()
vonSafeHandle
Instanzen frühzeitig, wenn möglich). Beachten Sie, dassSafeHandle
ist eigentlich Abstrakt, weil es viele verschiedene Arten von Griffen, die erfordern unterschiedliche Ansätze für die ordnungsgemäße Entsorgung und Handhabung.In Ihrem speziellen Fall, die Sie benötigen, zu betrachten, die Dokumentation der DLL, die Sie anrufen. Wenn es eine Win32-DLL, es gibt vielleicht schon ein SafeHandle-Typ für ihn. Wenn es eine Drittanbieter-DLL, dann können Sie Rollen Sie Ihre eigenen SafeHandle-Umsetzung - unter der Annahme, dass zusätzlich zu
Initialize()
gibt es eine version vonRelease()
(oder gleichwertig).Einige weitere interessante Leckerbissen über IntPtr vs SafeHandle finden Sie unter:
Verwenden SafeHandle zu Kapseln, systemeigene Ressourcen
SafeHandle-Klasse Referenz
SafeHandles und Kritischer Abschluss
IntPtr
64 bit nicht 65? Ich habe die edit-bitte zurück und erklären mehr (ich bin darauf vorbereitet zu sein, mein "jeden Tag etwas neues lernen moment).Gut, meine eigene SafeHandle-Implementierung wie gesagt ist keine große Sache, es gibt viele Beispiele auf. Was ich gerne wissen würde ist, wenn ich SafeHandle-und IntPtr austauschbar, somit könnte ich tun:
static extern bool Initialize([In] string name, out SafeHandle)
anstelle der aktuellenstatic extern bool Initialize([In] string name, out IntPtr)
?NÖ, das war nur ein Tippfehler meinerseits. Danke für den Fang.
Im Prinzip sollte in der Lage sein, um Ihre benutzerdefinierten
SafeHandle
-Derivat anstelle vonIntPtr
. Die interop-Marshalling-system hat eine spezielle Behandlung fürSafeHandles
. Allerdings schreiben Sie eine korrekt umgesetzt handle-Klasse benötigt Pflege. Lesen Sie den Abschnitt "Bemerkungen" unter SafeHandle-Klasse-Referenz als Ausgangspunkt.InformationsquelleAutor LBushkin