【问题标题】:Marshalling a VARIANT back from COM to C++ client将 VARIANT 从 COM 编组回 C++ 客户端
【发布时间】:2011-05-11 09:48:17
【问题描述】:

我正在尝试将来自 COM 对象的 BSTR 安全数组封送回 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;
}

以下是 C++ 客户端程序调用 GetStreams() 函数的方式:

VARIANT varStreamNames;
hr = spArchiveMgr->GetStreams( &varStreamNames );

我使用交互式调试器跟踪程序,一切似乎都正常工作(安全数组正确填充等),直到 GetStreams() 函数返回。此时,我收到“未处理的异常读取位置”消息。

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

【问题讨论】:

    标签: c++ com marshalling atl


    【解决方案1】:

    有两个问题。第一个是

     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;
    

    执行安全数组的浅拷贝 - 现在saStreamNamesvarOutNames 都拥有安全数组,因此当saStreamNames 在作用域结束时被销毁时,安全数组就会被释放。

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

    【讨论】:

    • 我尝试在客户端使用 CComVariant 类型,唉,我仍然遇到同样的错误,而且在同一点
    • @freefallr:是的,还有一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2017-12-19
    • 2010-10-03
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多