Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Okres istnienia wskaźników do interfejsów jest zawsze zarządzany za pośrednictwem metod AddRef i Release w każdym interfejsie COM. Aby uzyskać więcej informacji, zobacz Rules for Managing Reference Counts (Reguły zarządzania liczbami odwołań).
W przypadku wszystkich innych parametrów ważne jest, aby przestrzegać pewnych reguł zarządzania pamięcią. Następujące reguły mają zastosowanie do wszystkich parametrów metod interfejsu — w tym wartości zwracanej — które nie są przekazywane przez wartość:
- Parametry w parametrach muszą być przydzielane i zwalniane przez obiekt wywołujący.
- Parametry wychodzące muszą być przydzielane przez parametr o nazwie ; są one zwalniane przez obiekt wywołujący przy użyciu standardowego alokatora pamięci zadań COM. Aby uzyskać więcej informacji, zobacz alokator pamięci OLE.
- Parametry in/out są początkowo przydzielane przez obiekt wywołujący, a następnie zwalniane i ponownie przydzielane przez wywołaną, jeśli to konieczne. Podobnie jak w przypadku parametrów out, obiekt wywołujący jest odpowiedzialny za zwolnienie ostatecznej zwróconej wartości. Należy użyć standardowego alokatora pamięci COM.
W dwóch ostatnich przypadkach, w których jeden fragment kodu przydziela pamięć, a inny fragment kodu go zwalnia, przy użyciu alokatora COM zapewnia, że dwa fragmenty kodu korzystają z tych samych metod alokacji.
Innym obszarem, który wymaga szczególnej uwagi, jest leczenie parametrów out i in-out w warunkach awarii. Jeśli funkcja zwraca kod błędu, obiekt wywołujący zwykle nie ma możliwości wyczyszczenia parametrów out lub in-out. Prowadzi to do następujących dodatkowych reguł:
- W przypadku warunku błędu parametry muszą być zawsze niezawodnie ustawione na wartość, która zostanie wyczyszczona bez żadnej akcji przez obiekt wywołujący.
- Wszystkie parametry wskaźnika muszą być jawnie ustawione na wartość null. Są one zwykle przekazywane w parametrze wskaźnika do wskaźnika, ale mogą być również przekazywane jako elementy członkowskie struktury przydzielanej przez obiekt wywołujący i wywoływane wypełnienia kodu. Najprostszym sposobem upewnienia się, że jest to (częściowo) ustawienie tych wartości na wartość null we wpisie funkcji. Ta reguła jest ważna, ponieważ promuje bardziej niezawodną współdziałanie aplikacji.
- W warunkach błędu wszystkie parametry wystające muszą być pozostawione samodzielnie przez kod o nazwie (w związku z czym pozostają na wartości, do której zostały zainicjowane przez obiekt wywołujący) lub być jawnie ustawione, jak w przypadku zwracania błędu parametru out.
Należy pamiętać, że te konwencje zarządzania pamięcią dla aplikacji COM mają zastosowanie tylko w interfejsach publicznych i interfejsach API; w ogóle nie ma potrzeby, aby alokacja pamięci była ściśle wewnętrzna dla aplikacji COM, należy wykonać przy użyciu tych mechanizmów.
Warning
Typowe pułapki międzyoperacyjności .NET/ kodu zarządzanego: w przypadku korzystania z interfejsów COM z .NET (C# lub VB.NET) środowisko uruchomieniowe Callable Wrapper (RCW) automatycznie obsługuje większość zarządzania pamięcią. Jeśli jednak P/Invoke funkcji w stylu MODELU COM, która zwraca CoTaskMemAlloc-przydzielony ciąg (out LPWSTR), musisz go Marshal.FreeCoTaskMemzwolnić za pomocą — moduł odśmiecywania pamięci nie zwolni pamięci zadania COM:
// C# example — COM function returns a CoTaskMemAlloc'd string
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
static extern int SHGetKnownFolderPath(
ref Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr ppszPath);
// Caller must free the returned string
IntPtr pathPtr = IntPtr.Zero;
try
{
Guid folderId = new("374DE290-123F-4565-9164-39C4925E467B"); // Downloads
int hr = SHGetKnownFolderPath(ref folderId, 0, IntPtr.Zero, out pathPtr);
Marshal.ThrowExceptionForHR(hr);
string path = Marshal.PtrToStringUni(pathPtr)!;
}
finally
{
if (pathPtr != IntPtr.Zero)
Marshal.FreeCoTaskMem(pathPtr); // Required — prevents memory leak
}
Reguła kciuka: Jeśli natywna funkcja COM dokumentuje, że obiekt wywołujący musi zwolnić parametr wyjściowy z parametrem CoTaskMemFree, zarządzany odpowiednik to Marshal.FreeCoTaskMem. Nigdy nie używaj Marshal.FreeHGlobal pamięci zadań COM, ponieważ są to różne alokatory.
Com wewnętrznie używa zdalnych wywołań procedur (RPC) do komunikacji między klientami i serwerami. Aby uzyskać więcej informacji na temat zarządzania pamięcią w wycinkach serwera RPC, zobacz temat Server-stub Memory Management.