Tengo una función COM que debe devolver un SafeArray a través de un parámetro de salida LPSAFEARRAY*
. La función crea SafeArray usando la clase de plantilla CComSafeArray
de ATL. Mi aplicación ingenua utiliza CComSafeArray<T>::Detach()
con el fin de mover la propiedad de la variable local con el parámetro de salida:¿Cómo se devuelve un CComSafeArray local a un parámetro de salida 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;
}
El problema es que CComSafeArray::Detach()
realiza una operación Unlock
de modo que cuando el nuevo propietario de la SafeArray (principal sa
en este caso) se destruye, el bloqueo no es cero y Destroy
no puede desbloquear el SafeArray con E_UNEXPECTED
(esto provoca una pérdida de memoria debido a que SafeArray no está desasignado).
¿Cuál es la forma correcta de transferir la propiedad entre CComSafeArrays a través de un límite de método COM?
Editar: De la única respuesta hasta el momento parece que el error está en el lado del cliente (main
) y no del lado del servidor (foo
), pero me resulta difícil de creer que CComSafeArray
wasn Diseñado para este caso de uso trivial, debe haber una manera elegante de obtener un SafeArray de un método COM en un CComSafeArray
.
¿Qué versión de Visual Studio estás usando? –
Esto sucede tanto para VS8 (2005) como para VS9 (2008) – Motti
Basado en mi experiencia, creo que quien diseñó CComSafeArray nunca lo usó realmente. Puede usar su propia clase contenedora si lo desea. – Amnon