我有一个 COM 函数,它应该通过LPSAFEARRAY*out 参数返回一个 SafeArray。CComSafeArray该函数使用 ATL 的模板类创建 SafeArray 。我的幼稚实现使用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在这种情况下为 main)被破坏时,锁不为零并且Destroy无法解锁 SafeArray E_UNEXPECTED(这会导致内存泄漏,因为 SafeArray 不是解除分配)。
通过 COM 方法边界在 CComSafeArrays 之间转移所有权的正确方法是什么?
编辑:从目前的单一答案看来,错误出在客户端(main)而不是服务器端(foo),但我很难相信这CComSafeArray不是为这个琐碎的用例设计的,必须有将 SafeArray 从 COM 方法转换为CComSafeArray.