Wenn ich COM verwende, verwende ich normalerweise ATL-Smartpointer wie ATL::CComPtr
und ATL::CComBSTR
für die Ressourcenverwaltung. Aber einige der Methoden, die ich anrufe, verwenden Ausgabeparameter, um Zeiger auf zugewiesenen Speicher zurückzugeben, den ich freigeben muss. Zum Beispiel:Ausnahmesicheres Speicherhandling mit COM
WCHAR *pszName = nullptr;
if (SUCCEEDED(pShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszName))) {
DoSomething(pszName);
CoTaskMemFree(pszName);
}
anzumerken, dass GetDisplayName
Speicher für die Zeichenfolge zuordnet und gibt einen Zeiger auf ihn durch den Ausgangsparameter. Es liegt in der Verantwortung des Anrufers, diesen Speicher mit CoTaskMemFree
freizugeben.
Wenn DoSomething
eine Ausnahme auslöst, wird der obige Code undicht. Ich würde gerne eine Art von intelligenten Zeiger für pszName
verwenden, um solche Lecks zu vermeiden, aber die API braucht WCHAR**
, so dass ich nicht sehe, wie ich alles außer der Adresse eines dummen Zeigers übergeben kann. Da ich nicht die Zuteilung bin, kann ich RAII nicht verwenden.
I kann Verwendung RRID wenn ich ein deleter wie diese machen:
WCHAR *pszName = nullptr;
if (SUCCEEDED(pShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszName))) {
std::unique_ptr<WCHAR, CoTaskMemDeleter> guard(pszName);
DoSomething(pszName);
}
das funktioniert:
struct CoTaskMemDeleter {
void operator()(void *p) { ::CoTaskMemFree(p); }
};
Und dann sofort den zurückgegebenen Zeiger auf einen Standard-Smart-Pointer wie folgt zuweisen , aber es scheint fehleranfällig zu sein, eine zusätzliche Schutzvariable einzuführen. Zum Beispiel lässt dieser Ansatz pszName
auf den freigegebenen Speicher zeigen, so dass es leicht wäre, ihn versehentlich erneut zu verwenden.
Gibt es eine sauberere Möglichkeit, einen Smart-Pointer oder einen RAII-Wrapper für den vom COM-Server zugewiesenen Speicher zu verwenden, der vom Ausgabeparameter zurückgegeben wird? Fehle ich etwas, das ATL bietet?
Was ist so schlimm daran, die Erinnerung selbst zu befreien? Für mich scheint es sich nicht zu lohnen, etwas anderes zu tun. – evanmcdonnal
@evanmcdonnal: Ausnahmesicherheit. –