Ich habe eine COM-Funktion, die ein SafeArray über einen LPSAFEARRAY*
Out-Parameter zurückgeben sollte. Die Funktion erstellt SafeArray mit der ATL-Vorlagenklasse CComSafeArray
. Meine naive Implementierung verwendet CComSafeArray<T>::Detach()
, um das Eigentum von den lokalen Variablen auf den Ausgabeparameter zu bewegen:Wie gibt man ein lokales CComSafeArray an einen LPSAFEARRAY-Ausgabeparameter zurück?
void foo(LPSAFEARRAY* psa)
{
CComSafeArray<VARIANT> ret;
ret.Add(CComVariant(42));
*psa = ret.Detach();
}
int main()
{
CComSafeArray<VARIANT> sa;
foo(sa.GetSafeArrayPtr());
std::cout << sa[0].lVal << std::endl;
}
Das Problem ist, dass CComSafeArray::Detach()
eine Unlock
Operation durchführt, so dass, wenn der neue Besitzer des Safearray (Haupt der sa
in diesem Fall) ist zerstört das Schloss ist nicht Null und Destroy
schlägt das SafeArray mit E_UNEXPECTED
nicht frei (dies führt zu einem Speicherverlust, da das SafeArray nicht freigegeben ist).
Wie kann die Eigentumsübertragung zwischen CComSafeArrays über eine COM-Methodengrenze korrekt übertragen werden?
Edit: Von der einzigen Antwort so weit scheint es, dass der Fehler auf der Client-Seite ist (main
) und nicht von der Serverseite (foo
), aber ich finde es schwer zu glauben, dass CComSafeArray
wasn Für diesen trivialen Anwendungsfall muss es einen eleganten Weg geben, ein SafeArray aus einer COM-Methode in eine CComSafeArray
zu bekommen.
Welche Version von Visual Studio verwenden Sie? –
Dies passiert sowohl für VS8 (2005) als auch für VS9 (2008). – Motti
Basierend auf meiner Erfahrung glaube ich, wer auch immer CComSafeArray entworfen hat, hat es nie wirklich benutzt. Sie können Ihre eigene Wrapperklasse verwenden, wenn Sie möchten. – Amnon