Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Lebensdauer von Zeigern auf Schnittstellen wird immer über die AddRef- und Release- Methoden auf jeder COM-Schnittstelle verwaltet. Weitere Informationen finden Sie unter Rules for Managing Reference Counts.
Für alle anderen Parameter ist es wichtig, bestimmte Regeln für die Verwaltung des Arbeitsspeichers einzuhalten. Die folgenden Regeln gelten für alle Parameter von Schnittstellenmethoden, einschließlich des Rückgabewerts, die nicht nach Wert übergeben werden:
- Parameter müssen vom Aufrufer zugewiesen und freigegeben werden.
- Out-Parameters müssen von der aufgerufenen zugewiesen werden; sie werden vom Aufrufer mithilfe des standardmäßigen COM-Aufgabenspeicher-Allocators freigegeben. Weitere Informationen finden Sie unter Ole Memory Allocator.
- In/out-Parameters werden zunächst vom Aufrufer zugewiesen und dann bei Bedarf durch den aufgerufenen freigegeben und neu zugeordnet. Wie für out-Parameter gilt, ist der Aufrufer dafür verantwortlich, den endgültigen zurückgegebenen Wert freizugeben. Der standardmäßige COM-Speicherzuordnungsserver muss verwendet werden.
In den letzten beiden Fällen stellt die Verwendung des COM-Zuweisungsverteils sicher, dass die beiden Codeteile dieselben Zuordnungsmethoden verwenden, wenn ein Teil des Codes den Speicher zuweist und ein anderer Codeteil freigibt.
Ein weiterer Bereich, der besondere Aufmerksamkeit erfordert, ist die Behandlung von out- und in-out-Parametern bei Ausfallbedingungen. Wenn eine Funktion einen Fehlercode zurückgibt, hat der Aufrufer in der Regel keine Möglichkeit, die Out- oder In-Out-Parameter zu bereinigen. Dies führt zu den folgenden zusätzlichen Regeln:
- Bei einer Fehlerbedingung müssen Parameter immer zuverlässig auf einen Wert festgelegt werden, der ohne Aktion durch den Aufrufer bereinigt wird.
- Alle Zeigerparameter müssen explizit auf NULL-festgelegt werden. Diese werden in der Regel in einem Zeiger-zu-Zeiger-Parameter übergeben, können aber auch als Elemente einer Struktur übergeben werden, die der Aufrufer zuweist und die aufgerufenen Codefüllungen. Die einfachste Möglichkeit, um sicherzustellen, dass dies (teilweise) ist, um diese Werte auf NULL- für den Funktionseintrag festzulegen. Diese Regel ist wichtig, da sie eine stabilere Anwendungsinteroperabilität fördert.
- Unter Fehlerbedingungen müssen alle In-Out-Parameter entweder durch den aufgerufenen Code (also noch am Wert verbleiben, auf den sie vom Aufrufer initialisiert wurden) oder explizit festgelegt werden, wie im Ausgabeparameterfehler-Rückgabefall.
Beachten Sie, dass diese Speicherverwaltungskonventionen für COM-Anwendungen nur für öffentliche Schnittstellen und APIs gelten; es gibt überhaupt keine Anforderung, dass die Speicherzuweisung streng intern für eine COM-Anwendung mithilfe dieser Mechanismen erfolgen muss.
Warnung
Häufig auftretender Fall in .NET/Managed-Code-Interoperabilität: Bei der Verwendung von COM-Schnittstellen aus .NET (C# oder VB.NET) verarbeitet der Runtime Callable Wrapper (RCW) die meisten Speicherverwaltung automatisch. Wenn Sie jedoch eine COM-Stilfunktion aufrufen, die eine CoTaskMemAlloczugewiesene Zeichenfolge (out LPWSTR) zurückgibt, müssen Sie sie Marshal.FreeCoTaskMem freigeben – der Garbage Collector gibt keinen COM-Aufgabenspeicher frei:
// 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
}
Faustregel: Wenn eine systemeigene COM-Funktion dokumentiert, mit der der Aufrufer einen Out-Parameter freigeben CoTaskMemFreemuss, lautet Marshal.FreeCoTaskMemdie verwaltete Entsprechung . Verwenden Sie Marshal.FreeHGlobal niemals für DEN COM-Aufgabenspeicher, da es sich dabei um unterschiedliche Zuordnungen handelt.
COM verwendet intern Remoteprozeduraufrufe (RPC), um zwischen Clients und Servern zu kommunizieren. Weitere Informationen zum Verwalten von Arbeitsspeicher in RPC-Server-Stubs finden Sie im Thema Server-Stub Memory Management Thema.