У меня есть функция COM, которая должна возвращать SafeArray через параметр LPSAFEARRAY*
out.
Функция создает SafeArray с использованием класса шаблонов ATL CComSafeArray
.
Моя наивная реализация использует CComSafeArray<T>::Detach()
, чтобы переместить право собственности из локальной переменной в выходной параметр:
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;
}
Проблема заключается в том, что CComSafeArray::Detach()
выполняет операцию Unlock
, так что когда новый владелец SafeArray (основной sa
в этом случае) уничтожается, блокировка не равна нулю, а Destroy
не удается разблокировать SafeArray с E_UNEXPECTED
(это приводит к утечке памяти, поскольку SafeArray не освобождается).
Каков правильный способ передачи права собственности на CComSafeArrays через границу метода COM?
Изменить: От одного ответа до сих пор кажется, что ошибка на стороне клиента (main
), а не на стороне сервера (foo
), но мне трудно полагая, что CComSafeArray
не был разработан для этого тривиального случая использования, должен быть элегантный способ получить SafeArray из COM-метода в CComSafeArray
.