C++ 如何将本地CComSafeArray返回到LPSAFEARRAY输出参数?
我有一个COM函数,它应该通过C++ 如何将本地CComSafeArray返回到LPSAFEARRAY输出参数?,c++,com,atl,safearray,C++,Com,Atl,Safearray,我有一个COM函数,它应该通过LPSAFEARRAY*out参数返回一个SafeArray。 该函数使用ATL的CComSafeArray模板类创建SafeArray。 我的naive实现使用CComSafeArray::Detach()将所有权从局部变量移动到输出参数: void foo(LPSAFEARRAY* psa) { CComSafeArray<VARIANT> ret; ret.Add(CComVariant(42)); *psa = ret.D
LPSAFEARRAY*
out参数返回一个SafeArray。
该函数使用ATL的CComSafeArray
模板类创建SafeArray。
我的naive实现使用CComSafeArray::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;
}
void foo(LPSAFEARRAY*psa)
{
雷特;
ret.Add(CComVariant(42));
*psa=重新分离();
}
int main()
{
库姆萨雷;
foo(sa.GetSafeArrayPtr());
std::cout问题在于您直接设置了接收CComSafeArray
的内部指针。
使用Attach()
方法将现有的SAFEARRAY
附加到CComSafeArray
:
LPSAFEARRAY ar;
foo(&ar);
CComSafeArray<VARIANT> sa;
sa.Attach(ar);
lpar;
foo&ar;
库姆萨雷;
附加(ar);
我猜where无意允许这样的用例。可能不是同一个开发人员编写了CComVariant
&CComPtr
:)
我相信,CComSafeArray
的作者将值语义视为主要目标;附加/分离可能只是一个“额外”功能。只是为了确认标记的答案是正确的。RAII包装器无法跨COM边界工作
发布的方法实现不正确,您不能假设调用方将提供有效的SAFEARRAY。只是[out]在Automation中不是有效的属性,它必须是[out,retval]或[in,out]。如果它是[out,retval],看起来就是这样,那么该方法必须从头创建一个新数组。如果它是[in,out]然后,如果传入的数组与预期的数组类型不匹配,则该方法必须销毁该数组并创建一个新的数组。当然这不是CComSafeArray
应该使用的方式,它违背了CComVariant
和CComBSTR
的粒度。正如您在代码中看到的,CComSafeArray预期SAFEARRAY是locked。你必须以某种方式锁定它。没有类似附加的功能可以锁定,也没有类似分离的功能不能解锁-因此工作必须在调用者或被调用者端完成。你正在使用哪个版本的Visual Studio?VS8(2005)和VS9(2008)都会发生这种情况根据我的经验,我相信设计CComSafeArray的人从来没有真正使用过它。如果你愿意,你可以使用自己的包装器类。即使有这样的理由,我仍然觉得CComSafeArray
的默认ctor和GetSafeAraryPTR
是设计缺陷/解决方法。。。