我有一个COM函数,应该通过LPSAFEARRAY*
out参数返回一个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方法边界在CComSafeArrays之间转移所有权的正确方法是什么?
编辑:到目前为止,从单个答案来看,错误似乎是在客户端(
main
)而不是在服务器端(foo
),但是我很难相信CComSafeArray
不是为此琐碎的用途而设计的-case,必须有一种优雅的方法将SafeArray从COM方法中获取到CComSafeArray
中。 最佳答案
问题是您直接设置了接收CComSafeArray
的内部指针。
使用Attach()
方法将现有的SAFEARRAY
附加到CComSafeArray
:
LPSAFEARRAY ar;
foo(&ar);
CComSafeArray<VARIANT> sa;
sa.Attach(ar);
关于c++ - 如何将本地CComSafeArray返回到LPSAFEARRAY输出参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1778491/