我有一个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/

10-11 22:49