Packing a array inside a VARIANT (VC++ 6.0) (Series 3 of N)

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.

  1. 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.
  2. creating a safe array of the desired (VT_U1) type.
  3. copying the temporary buffer to the safe array of the variant.
  4. 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.

2 comments

Leave a Reply to http://www.bedrecycling.co.Uk/ Cancel reply

Your email address will not be published. Required fields are marked *