Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.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++ 将变量从COM编组回C++;客户_C++_Com_Marshalling_Atl - Fatal编程技术网

C++ 将变量从COM编组回C++;客户

C++ 将变量从COM编组回C++;客户,c++,com,marshalling,atl,C++,Com,Marshalling,Atl,我试图从一个COM对象中把BSTRS的安全射线整理成一个C++客户端应用程序。 所涉及函数的IDL定义: [id(5), helpstring("method GetStreams")] HRESULT GetStreams( [out,retval] VARIANT* pvarStreamNames ); 下面是我对GetStreams()函数的实现: STDMETHODIMP CArchiveManager::GetStreams(VARIANT* pvarStreamNames

我试图从一个COM对象中把BSTRS的安全射线整理成一个C++客户端应用程序。 所涉及函数的IDL定义:

[id(5), helpstring("method GetStreams")] 
    HRESULT GetStreams( [out,retval] VARIANT* pvarStreamNames );
下面是我对GetStreams()函数的实现:

STDMETHODIMP CArchiveManager::GetStreams(VARIANT* pvarStreamNames)
{   
CComSafeArray<BSTR, VT_BSTR>    saStreamNames;
CComVariant                     varOutNames;

Stream* pNext       = NULL;
int     nNumStreams = m_Streams.NumStreams();

if( nNumStreams == 0 )
    return S_OK;

for(int x = 0; x < nNumStreams; x++)
{
    pNext = m_Streams.GetAt(x); 
    if( pNext )             
        saStreamNames.Add( pNext->StreamName() );   
}

if( saStreamNames.GetCount() > 0 )
{
    varOutNames.vt      = VT_ARRAY;
    varOutNames.parray  = saStreamNames.m_psa;

    varOutNames.Detach(pvarStreamNames);
}

return S_OK;
}
VARIANT varStreamNames;
hr = spArchiveMgr->GetStreams( &varStreamNames );
我使用交互式调试器跟踪整个程序,在GetStreams()函数返回之前,一切都正常工作(safearray正确填充等)。此时,我收到一条“未处理的异常读取位置”消息


关于如何调试/解决此问题的建议?

有两个问题。第一个是

 VARIANT varStreamNames;
是统一的,那么什么时候呢

varOutNames.Detach(pvarStreamNames);
在未初始化的变量上运行它调用
VariantClear()
,这会导致未定义的行为-程序崩溃

在调用COM方法之前,您必须在
varStreamNames
上调用
VariantInit()
,或者只需为
varStreamNames
使用
CComVariant
类型

第二个是:

CComSafeArray<BSTR, VT_BSTR>    saStreamNames;
CComVariant                     varOutNames;

varOutNames.vt      = VT_ARRAY;
varOutNames.parray  = saStreamNames.m_psa;
CComSafeArray saStreamNames;
cCOMVariantvaroutnames;
varOutNames.vt=vt_数组;
varOutNames.parray=saStreamNames.m_psa;
执行安全阵列的浅层副本-现在
saStreamNames
varOutNames
都拥有安全阵列,因此当
saStreamNames
在作用域结束时被销毁时,安全阵列将被释放


由于您已将相同的安全数组地址复制到
pvarStreamNames
中,现在您得到了一个带有悬挂安全数组指针的变体。尝试访问该安全数组是未定义的行为。您应该使用
CComSafeArray
Detach()
方法来释放所有权。

我已经尝试在客户端使用CComVariant类型,唉,我仍然得到相同的错误,而且是相同的错误point@freefallr:是的,还有一个问题。