Przeszukałem internet daleko, ale nie znalazłem dobrego wyjaśnienia.Czy mogę używać SafeHandle zamiast IntPtr?
Moje pytanie jest dość proste.
Mam DLL, który ma funkcję o nazwie Initialize, a jednym z parametrów jest wskaźnik, który otrzyma uchwyt, który będzie używany z kolejnymi połączeniami. Kolejnym parametrem jest ciąg znaków, który opiszę pod kątem kompletności. Podpis używam jest (w prostej formie):
[DllImport(MyDll)]
static extern bool Initialize([In] string name, out IntPtr handle);
podpis w samej DLL jest zapisana jako: Initialize(LPTSTR name, HANDLE handle)
z komentarzem „Rękojeść: wskaźnik do lokalizacji, która otrzyma uchwyt”.
i późniejsze rozmowy są w formie
[DllImport(MyDll)]
static extern bool DoSomething(IntPtr handle, uint randomParameter);
Czytałem o SafeHandle
i zastanawiałem się, czy mogę użyć go do substite dla mojego uchwytu IntPtr. A jeśli mogę, jak mam to zrobić? Rozszerzenie abstrakcyjnej klasy SafeHandle nie jest problemem, ale czy mogę bezpośrednio zastąpić moją IntPtr dla SafeHandle (i użyć domyślnego systemu Marshalling), czy też muszę zrobić coś ekstra?
Jakie korzyści ma 'SafeHandle' dać wam, że tylko przechowywanie w' IntPtr' nie? –
@ScottChamberlain - 'SafeHandle' jest' IDisposable' i zapewnia, że zasoby przywoływane przez uchwyt są wypuszczane.'IntPtr' to po prostu wartość wielkości wskaźnika, którą można przekazać - nie ma żadnej semantyki związanej z usuwaniem. – LBushkin
Zakładając, że możesz pobierać opłaty za pamięć, chyba że możesz zwolnić pamięć wskaźnika za pomocą 'Marshal.FreeBSTR',' Marshal.FreeCoTaskMem' lub 'Marshal.FreeHGlobal', nie sądzę, że możesz bezpiecznie -dokonuj pamięć z C#. Używając 'IntPtr', C# nie spróbuje automatycznie zwolnić pamięci. – Pooven