Po pierwsze: mówimy tu o COM Interop (ITaskTrigger
jest interfejsem COM), a nie P/Invoke. Dla tych dwóch zasad obowiązują różne zasady, dlatego ważne jest, aby zachować je w dobrym stanie. Na przykład musisz zdefiniować wrappery C# dla całego interfejsu, a nie tylko żądaną metodę. Powinny one zacząć: pinvoke.net
Krótka odpowiedź brzmi: masz szczęście, ponieważ CLR powinien właściwie zająć się sprawami.
Dłuższa odpowiedź obejmuje różne typy układania, w zależności od typów parametrów, kierunków i atrybutów dodawanych do podpisów interopowych.
W tym przypadku typ parametru, który otrzymasz w wywołaniu, jest parametrem "out string
", z atrybutem MarshalAs(UnmanagedType.LPWSTR)
. Gdy serwer COM ujawnia wywołanie, które ma parametr "out" o typie łańcucha LPWSTR
, zakładając, że serwer utrzymuje koniec transakcji, przydzieli bufor pamięci z numerem CoTaskMemAlloc()
i zwróci go tobie. (Jeśli był to inny typ ciągu, np. BSTR
, to specyficzne wywołanie przydziału pamięci może być inne, ale podstawowa koncepcja jest taka sama.) W tym momencie jesteś odpowiedzialny za wyczyszczenie pamięci, kiedy już jej nie potrzebujesz, używając zgodnego połączenia CoTaskMemFree()
.
Jest to specjalny rodzaj operacji nazywany jest „zmiana odniesienia”: parametr wysyłasz w już jest parametrem odniesienia, ale serwer COM będzie zastąpić go z innym odniesienia. Dobre wyjaśnienie tego procesu można znaleźć w sekcji "Własność pamięci" pod adresem this MSDN magazine article. Jak widać z tego artykułu, gdy CLR otrzymuje dane z powrotem z parametru "out" w typie referencyjnym, uznaje, że bierze odpowiedzialność za uwolnienie tej pamięci. Podczas przekazywania tego wywołania do kodu zarządzanego używa on atrybutu MarshalAs
, aby ustalić, że jest to wskaźnik typu string w postaci modelu LPWSTR
w COM, i że powinien on zostać przydzielony przy użyciu CoTaskMemAlloc()
. Po utworzeniu zarządzanego ciągu danych, wywoła on w Twoim imieniu CoTaskMemFree()
na oryginalnym buforze. Dane, które otrzymasz, będą w pełni zarządzane i nie będziesz musiał zajmować się problemami własności.
Zobacz, jak pracować z typem dynamicznym za pomocą COM Interop - może to znacznie ułatwić pisanie statyczne i zapewnia zarządzanie pamięcią. – weismat
Czy masz jakieś odniesienia do tego ostatniego fragmentu? C# już zarządza pamięcią dla współdziałania COM i zawsze ma. Typy dynamiczne ułatwiają pracę z np. Interfejsem IDispatch, ale czy mają inne funkcje zarządzania pamięcią niż statyczne typy interopów? –