我有一个COM函数,应该通过LPSAFEARRAY*
输出参数返回一个SafeArray。
该函数使用ATL的CComSafeArray
模板类创建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
)被销毁时,锁定计数不为零,导致Destroy
无法通过E_UNEXPECTED
解锁SafeArray(这会导致内存泄漏,因为SafeArray未被释放)。如何正确地在COM方法边界之间传递两个CComSafeArray之间的所有权?
编辑:从迄今为止的单个答案来看,错误似乎出现在客户端(
main
)而不是服务器端(foo
),但我很难相信 CComSafeArray
没有为这种微不足道的用例设计,必须有一种优雅的方法将SafeArray从COM方法中提取到CComSafeArray
中。