¿Cómo se devuelve una CComSafeArray local a un parámetro de salida LPSAFEARRAY?

Tengo una función COM que debería devolver un SafeArray a través de unLPSAFEARRAY* fuera de parámetro. La función crea el SafeArray utilizando ATLCComSafeArray plantilla de plantilla. Mis usos ingenuos de implementaciónCComSafeArray<T>::Detach() para mover la propiedad de la variable local al parámetro de salida:

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 eseCComSafeArray::Detach() realiza unUnlock operación para que cuando el nuevo propietario de SafeArray (mainsa en este caso) se destruye el bloqueo no es cero yDestroy falla al desbloquear el SafeArray conE_UNEXPECTED (Esto lleva a una pérdida de memoria ya que SafeArray no está desasignado).

¿Cuál es la forma correcta de transferir la propiedad a CComSafeArrays a través de un límite de método COM?

Editar: De la única respuesta hasta ahora parece que el error está en el lado del cliente (main) y no desde el lado del servidor (foo), pero me cuesta creerloCComSafeArray no fue diseñado para este caso de uso trivial, debe haber una manera elegante de obtener un SafeArray de un método COM en unCComSafeArray.

Respuestas a la pregunta(3)

Su respuesta a la pregunta