C++ 将变量从COM编组回C++;客户
我试图从一个COM对象中把BSTRS的安全射线整理成一个C++客户端应用程序。 所涉及函数的IDL定义: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
[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:是的,还有一个问题。