Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将本地CComSafeArray返回到LPSAFEARRAY输出参数?_C++_Com_Atl_Safearray - Fatal编程技术网

C++ 如何将本地CComSafeArray返回到LPSAFEARRAY输出参数?

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

我有一个COM函数,它应该通过
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
是设计缺陷/解决方法。。。