gpt4 book ai didi

c++ - 将 VARIANT 从 COM 编码回 C++ 客户端

转载 作者:行者123 更新时间:2023-11-30 03:09:19 27 4
gpt4 key购买 nike

我正在尝试将来自 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 );

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

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

最佳答案

有两个问题。第一个是

 VARIANT varStreamNames;

是单元化的,所以当

varOutNames.Detach(pvarStreamNames);

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

您必须调用 VariantInit()varStreamNames在调用 COM 方法之前或只使用 CComVariant输入 varStreamNames .

第二个是:

CComSafeArray<BSTR, VT_BSTR>    saStreamNames;
CComVariant varOutNames;

varOutNames.vt = VT_ARRAY;
varOutNames.parray = saStreamNames.m_psa;

执行安全数组的浅拷贝 - 现在都是 saStreamNamesvarOutNames拥有安全阵列等saStreamNames在释放安全数组的范围末尾被销毁。

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

关于c++ - 将 VARIANT 从 COM 编码回 C++ 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4204488/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com