Search code examples
c++arrayscomvariantsafearray

How do you access to SAFE ARRAY in a VARIANT data type returned from a COM object in C++?


I am working with a COM object. I Call a function of COM objects and this functin return VARIANT data type that contain SAFE ARRAY of my equipments list. How can I work with this VARIANT to access to SAFEARRY of my equipments.

  VARIANT namList; 
  SAFEARRAY* myequip;
  namList=str->GetNames();

Solution

  • In order to use a SAFEARRAY in a VARIANT like this, you need to do a lot of validation and error-checking. Here's the rough pattern you'll need to follow. Please read the comments carefully, as I have made some assumptions about the COM API that you're using.

    // verify that it's an array
    if (V_ISARRAY(&namList))
    {
        // get safe array
        LPSAFEARRAY pSafeArray = V_ARRAY(&namList);
    
        // determine the type of item in the array
        VARTYPE itemType;
        if (SUCCEEDED(SafeArrayGetVartype(pSafeArray, &itemType)))
        {
            // verify it's the type you expect
            // (The API you're using probably returns a safearray of VARIANTs,
            // so I'll use VT_VARIANT here. You should double-check this.)
            if (itemType == VT_VARIANT)
            {
                // verify that it's a one-dimensional array
                // (The API you're using probably returns a one-dimensional array.)
                if (SafeArrayGetDim(pSafeArray) == 1)
                {
                    // determine the upper and lower bounds of the first dimension
                    LONG lBound;
                    LONG uBound;
                    if (SUCCEEDED(SafeArrayGetLBound(pSafeArray, 1, &lBound)) && SUCCEEDED(SafeArrayGetUBound(pSafeArray, 1, &uBound)))
                    {
                        // determine the number of items in the array
                        LONG itemCount = uBound - lBound + 1;
    
                        // begin accessing data
                        LPVOID pData;
                        if (SUCCEEDED(SafeArrayAccessData(pSafeArray, &pData)))
                        {
                            // here you can cast pData to an array (pointer) of the type you expect
                            // (The API you're using probably returns a safearray of VARIANTs,
                            // so I'll use VARIANT here. You should double-check this.)
                            VARIANT* pItems = (VARIANT*)pData;
    
                            // use the data here.
    
                            // end accessing data
                            SafeArrayUnaccessData(pSafeArray);
                        }
                    }
                }
            }
        }
    }