Search code examples
winapicomsafearray

SAFEARRAY data to unsigned char*


I am trying to convert a SAFEARRAY data pointer to unsinged char*. However I am not getting the expected data. Here is a snippet.

SafeArrayLock(psaFrameData);
psaFrameData->rgsabound->cElements;
int nCount = psaFrameData->rgsabound->cElements -   psaFrameData->rgsabound->lLbound + 1;
frameData = new unsigned char[nCount];
memset(frameData, 0, nCount);

for (int i = 0; i < nCount; ++i)
{
    frameData[i] = ((unsigned char*)(psaFrameData)->pvData)[i];
}    
SafeArrayUnlock(psaFrameData);

Solution

  • Do not manually lock the array and then access its pvData (or any of its other data members) directly. Use the various accessors functions instead, such as SafeArrayAccessData():

    Increments the lock count of an array, and retrieves a pointer to the array data.

    Try something more like this:

    // safety check: make sure the array has only 1 dimension...
    if (SafeArrayGetDim(psaFrameData) != 1)
    {
        // handle the error ...
    }
    else
    {
        // safety check: make sure the array contains byte elements...
        VARTYPE vt = 0;
        SafeArrayGetVartype(psaFrameData, &vt);
        if (vt != VT_UI1)
        {
            // handle the error ...
        }
        else
        {
            // get a pointer to the array's byte data...
            unsigned char *data;
            if (FAILED(SafeArrayAccessData(psaFrameData, (void**)&data)))
            {
                // handle the error ...
            }
            else
            {
                // calculate the number of bytes in the array...
                LONG lBound, uBound;
                SafeArrayGetLBound(psaFrameData, 1, &lBound);
                SafeArrayGetUBound(psaFrameData, 1, &uBound);
                long nCount = uBound - lBound + 1; 
    
                // copy the bytes...
                frameData = new unsigned char[nCount];
                memcpy(frameData, data, nCount);
    
                // release the pointer to the array's byte data...
                SafeArrayUnaccessData(psaFrameData);
            }
        }
    }