COM编程--字符串结构体转换

本文介绍如何将自定义结构体转换为VARIANT类型的安全数组,并提供了详细的代码实现及解析过程。通过构造安全数组,可以方便地在COM组件间传递复杂数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、将结构体保存到VARIANT中

// @desc : 转为安全数组
	HRESULT Hr;
	SAFEARRAY *	pSArray;
	CComQIPtr<IRecordInfo> spRecordInfo;
	Hr = ::GetRecordInfoFromGuids(LIBID_VT_CommUtiLib, 1, 0, LOCALE_USER_DEFAULT, __uuidof(TAvailableRoom), &spRecordInfo);
	if( S_OK != Hr ) {
		return;
	}

	pSArray = ::SafeArrayCreateVectorEx( VT_RECORD, 0, nSize, (void*)spRecordInfo );
	TAvailableRoom* pData = NULL;
	Hr = ::SafeArrayAccessData(pSArray,(void**)&pData);
	TAvailableRoom *pDElement;
	for( LONG n = 0; n < nSize; n++ )
	{
		// @desc : 
		SM_MEETINGINFO& SElementRef = vtMeetingRoom[n];
		pDElement = &pData[n];

		// @desc : Copy
		pDElement->nConfID	= SElementRef.nConfID;		
		pDElement->bstrConfName = CComBSTR( SElementRef.szConfName ).Detach();		
		pDElement->nMaxCount = SElementRef.wMaxCount;		
		pDElement->nCurCount = SElementRef.wCurCount;
	}
	::SafeArrayUnaccessData( pSArray );

V_ARRAY( pVal ) = pSArray;
V_VT( pVal ) = VT_ARRAY | VT_RECORD;


调用:

VARIANT varArray;
GetAvailableRooms(&varArray);
GetAvailableRooms( VARIANT * pVal, LONG *pnErrCode)


解析:

CSafeArrayWarper arrConf;
arrConf.Attach(variant.parray);
	CString sVal;
	LONG nMaxSize = arrConf.GetCount();
	if (nMaxSize)
	{
		TVTRoomAvailable* pData = NULL;
		TVTRoomAvailable* pEle = NULL;
		HRESULT hr = arrConf.AccessData((void**)&pData);
		ASSERT(SUCCEEDED(hr));
		for (LONG i = arrConf.GetLowerBound(); i < nMaxSize; i++)
		{
			pEle = &pData[i];

			sVal = pEle->bstrConfName;
			SM_MEETINGINFO* pInfo = new SM_MEETINGINFO;
			if (pInfo)
			{
				_stprintf_s(pInfo->szConfName, _countof(pInfo->szConfName), _T("%s"), pEle->bstrConfName);
				pInfo->nConfID = pEle->nConfID;
				pInfo->wMaxCount = pEle->nMaxCount;
				pInfo->wCurCount = pEle->nCurCount;

				m_vecMeetingInfo.push_back(pInfo);
			}
		}

		arrConf.UnAccessData();
	}
	arrConf.Detach();

#pragma once

class CSafeArrayWarper
{
public:
	CSafeArrayWarper(void) : m_psa(NULL) {};
	~CSafeArrayWarper(void) {
		HRESULT hRes = Destroy();
		ATLASSERT(SUCCEEDED(hRes));
	};

public:
	HRESULT Attach(const SAFEARRAY *psaSrc) 
	{
		HRESULT hRes = S_OK;
		m_psa = const_cast<LPSAFEARRAY>(psaSrc);
		hRes = Lock();
		return hRes;
	}
	LPSAFEARRAY Detach()
	{
		Unlock();
		LPSAFEARRAY pTemp = m_psa;
		m_psa = NULL;
		return pTemp;
	} 
	HRESULT Destroy()
	{
		HRESULT hRes = S_OK;
		if (m_psa != NULL)
		{
			hRes = Unlock();
			if (SUCCEEDED(hRes))
			{
				hRes = SafeArrayDestroy(m_psa);
				if (SUCCEEDED(hRes))
					m_psa = NULL;
			}
		}
		return hRes;
	}

public:
	LPSAFEARRAY* GetSafeArrayPtr() throw()
	{
		return &m_psa;
	}
	HRESULT GetSafeArrayData(void HUGEP** ppvData) throw()
	{
		HRESULT hRes = S_OK;
		if (m_psa != NULL)
		{
			hRes = ::SafeArrayAccessData(m_psa, ppvData);
		}
		return hRes;
	}
	LONG GetLowerBound(UINT uDim = 0) const
	{
		ATLASSUME(m_psa != NULL);
		LONG lLBound = 0;
		HRESULT hRes = SafeArrayGetLBound(m_psa, uDim+1, &lLBound);
		if (FAILED(hRes))
			AtlThrow(hRes);
		return lLBound;
	}
	LONG GetUpperBound(UINT uDim = 0) const
	{
		ATLASSUME(m_psa != NULL);
		LONG lUBound = 0;
		HRESULT hRes = SafeArrayGetUBound(m_psa, uDim+1, &lUBound);
		if (FAILED(hRes))
			AtlThrow(hRes);
		return lUBound;
	}
	ULONG GetCount(UINT uDim = 0) const
	{
		ATLASSUME(m_psa != NULL);
		ATLASSERT(uDim < GetDimensions());
		LONG lLBound, lUBound;
		HRESULT hRes = SafeArrayGetLBound(m_psa, uDim+1, &lLBound);
		ATLASSERT(SUCCEEDED(hRes));
		if(FAILED(hRes))
			AtlThrow(hRes);
		hRes = SafeArrayGetUBound(m_psa, uDim+1, &lUBound);
		ATLASSERT(SUCCEEDED(hRes));
		if(FAILED(hRes))
			AtlThrow(hRes);
		return (lUBound - lLBound + 1);
	}
	UINT GetDimensions() const
	{
		ATLASSUME(m_psa != NULL);
		return SafeArrayGetDim(m_psa);
	}
	bool IsSizable() const
	{
		ATLASSUME(m_psa != NULL);
		if(m_psa == NULL)
			AtlThrow(E_FAIL);

		return (m_psa->fFeatures & FADF_FIXEDSIZE) ? false : true;
	}

public:
// 	void HUGEP* GetAt(LONG lIndex) const
// 	{
// 		ATLASSUME(m_psa != NULL);
// 		if(m_psa == NULL)
// 			AtlThrow(E_FAIL);
// 
// 		LONG lLBound = GetLowerBound();
// 		ATLASSERT(lIndex >= lLBound);
// 		ATLASSERT(lIndex <= GetUpperBound());
// 		if ((lIndex < lLBound) || (lIndex > GetUpperBound()))
// 			AtlThrow(E_INVALIDARG);
// 
// 		return ((_ATL_AutomationType<T>::_typewrapper*)m_psa->pvData)[lIndex-lLBound];
// 	}
// 
// 	typename _ATL_AutomationType<T>::_typewrapper& GetAt(LONG lIndex)
// 	{
// 		ATLASSUME(m_psa != NULL);
// 		if(m_psa == NULL)
// 			AtlThrow(E_FAIL);
// 
// 		LONG lLBound = GetLowerBound();
// 		ATLASSERT(lIndex >= lLBound);
// 		ATLASSERT(lIndex <= GetUpperBound());
// 		if ((lIndex < lLBound) || (lIndex > GetUpperBound()))
// 			AtlThrow(E_INVALIDARG);
// 
// 		return ((_ATL_AutomationType<T>::_typewrapper*)m_psa->pvData)[lIndex-lLBound];
// 	}

protected:
	HRESULT Lock()
	{
		return S_OK;

// 		ATLASSUME(m_psa != NULL);
// 		return SafeArrayLock(m_psa);
	}
	HRESULT Unlock()
	{
		return S_OK;

// 		ATLASSUME(m_psa != NULL);
// 		return SafeArrayUnlock(m_psa);
	}

private:
	SAFEARRAY* m_psa;
};





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值