Ho una funzione COM che dovrebbe restituire un SafeArray tramite un parametro out LPSAFEARRAY*
. La funzione crea SafeArray utilizzando la classe di modello CComSafeArray
di ATL. mio ingenuo attuazione utilizza CComSafeArray<T>::Detach()
al fine di spostare la proprietà dalla variabile locale al parametro di uscita:Come si restituisce un CComSafeArray locale su un parametro di uscita LPSAFEARRAY?
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;
}
Il problema è che CComSafeArray::Detach()
esegue un'operazione Unlock
in modo che quando il nuovo proprietario del SafeArray (principale sa
in questo caso) viene distrutto il blocco non è zero e Destroy
non riesce a sbloccare SafeArray con E_UNEXPECTED
(questo porta a una perdita di memoria poiché SafeArray non è deallocato).
Qual è il modo corretto per trasferire la proprietà tra CComSafeArrays attraverso un limite del metodo COM?
Edit: Dalla sola risposta finora sembra che l'errore sia sul lato client (main
) e non dal lato server (foo
), ma trovo difficile credere che CComSafeArray
wasn Progettato per questo banale caso d'uso, ci deve essere un modo elegante per ottenere un SafeArray da un metodo COM in uno CComSafeArray
.
Quale versione di Visual Studio stai utilizzando? –
Questo accade sia per VS8 (2005) che per VS9 (2008) – Motti
In base alla mia esperienza, credo che chiunque abbia progettato CComSafeArray non l'abbia mai effettivamente utilizzata. Puoi usare la tua classe di wrapper se vuoi. – Amnon