This is the third post about variant, in this post I I am going to explain, how an array of structures can be packed inside a VARIANT variable. suppose we have a structure as definition shown below.
typedef struct MyStructType
{
int nID ;
long lVal ;
double dblVal ;
TCHAR szBuffer[255];
} MyStructType ;
Packing a array of structure inside a Variant
int PackVariantWithStructArray(short nCnt, VARIANT * pVar )
{
// TODO: Add your dispatch handler code here
USES_CONVERSION ;
//Initialize the VARIANT (Type is SAFEARRAY of BYTE)
VariantInit(pVar);
pVar->vt = VT_ARRAY | VT_UI1 ;
int nBufferSize = nCnt * sizeof ( MyStructType );
// Define a safe array of nCnt Item and Starting index as 0
SAFEARRAYBOUND safeBounds = { nBufferSize, 0};
//Create the Safe Array passing it the bounds
SAFEARRAY* pSafeArray = SafeArrayCreate(VT_UI1, 1, &safeBounds);
//Get a pointer to the array data, This actually increments the array’s lock count)
MyStructType * structArray = NULL;
SafeArrayAccessData(pSafeArray, (void**)&structArray);
for ( int i = 0 ; i < nCnt ; i++ )
{
CString strTmp ;
strTmp.Format ( _T("This is Item %2d"), i );
structArray[i].dblVal = (i +1) * 101.0 ;
structArray[i].lVal = (i +1) * 11 ;
structArray[i].nID = (i +1) ;
_tcscpy ( structArray[i].szBuffer, strTmp) ;
}
// We are done wth populating the array Decrement the lock
SafeArrayUnaccessData(pSafeArray);
//Assign our VARIANT out param with the array
pVar->parray = pSafeArray ;
return nCnt ;
}
as it can be seen from the above code, here I have just created a byte buffer sufficient to accommodate the all structures,
it involves following steps.
- Allocating the desired temporary buffer space to hold the array of structures (that should be equivalent to (number of structure x size of structure), and filling that array with values one need to return.
- creating a safe array of the desired (VT_U1) type.
- copying the temporary buffer to the safe array of the variant.
- free the memory allocated for temporary buffer. (avoid memory leaks).
Fetching a array of structure from a variant.
MyStructType * UnPackVariantWithStructArray(short nCount, VARIANT var )
{
MyStructType *pBuffer = (MyStructType *) calloc ( nCount, sizeof (MyStructType)) ;
USES_CONVERSION ;
SAFEARRAY* pSafeArray = var.parray ;
//Get a pointer to the array data, This actually increments the array’s lock count)
MyStructType *structArray = NULL ;
SafeArrayAccessData ( pSafeArray, (void**)&structArray );
for ( int i = 0 ; i < nCount ; i++ )
{
pBuffer[ i].dblVal = structArray [i].dblVal ;
pBuffer[ i].lVal = structArray [i].lVal ;
pBuffer[ i].nID = structArray [i].nID ;
pBuffer[ i].dblVal = structArray [i].dblVal ;
_tcscpy ( pBuffer[ i].szBuffer, structArray [i].szBuffer );
}
// We are done wth populating the array Decrement the array’s lock count
SafeArrayUnaccessData(pSafeArray);
return pBuffer ;
}
this is a crude method, although there is a better method using type libraries, that I will explain in some other article.
Your mode of telling the wholᥱ thing in this paragraph is genuіnely pleasant, every one be able to effortlessⅼy
undeгstand it, Thanks a lot.
Great article! We will be linking to this particularly great
content on our site. Keep up the good writing.