SAFEARRAY Data Type

The definition for a safe array varies, depending on the target operating system platform. On 32-bit Windows systems, both the cbElements and cLocks parameters are unsigned long integers, and the handle parameter is omitted. On 16-bit Windows systems, cbElements and cLocks are unsigned short integers The handle parameter is retained for compatibility with earlier software. For example:

typedef struct FARSTRUCT tagSAFEARRAY {
    unsigned short cDims;         // Count of dimensions in this array.
    unsigned short fFeatures;    // Flags used by the SafeArray
                                // routines documented below.
#if defined(WIN32)
    unsigned long cbElements;    // Size of an element of the array.
                                // Does not include size of
                                // pointed-to data.
    unsigned long cLocks;        // Number of times the array has been 
                                // locked without corresponding unlock.
#else
    unsigned short cbElements;
    unsigned short cLocks;
    unsigned long handle;        // Unused but kept for compatibility.
#endif
    void HUGEP* pvData;                 // Pointer to the data.
    SAFEARRAYBOUND rgsabound[1];        // One bound for each dimension.
} SAFEARRAY;

The array rgsabound is stored with the left-most dimension in rgsabound[0] and the right-most dimension in rgsabound[cDims 1]. If an array was specified in a C-like syntax as a [2][5], it would have two elements in the rgsabound vector. Element 0 has an lLbound of 0 and a cElements of 2. Element 1 has an lLbound of 0 and a cElements of 5.

The fFeatures flags describe attributes of an array that can affect how the array is released. This allows freeing the array without referencing its containing variant. The bits are accessed using the following constants:

#define FADF_AUTO        0x0001    // Array is allocated on the stack.
#define FADF_STATIC        0x0002    // Array is statically allocated.
#define FADF_EMBEDDED    0x0004    // Array is embedded in a structure.
#define FADF_FIXEDSIZE    0x0010    // Array may not be resized or 
                                // reallocated.
#define FADF_BSTR        0x0100    // An array of BSTRs.
#define FADF_UNKNOWN        0x0200    // An array of IUnknown*.
#define FADF_DISPATCH    0x0400    // An array of IDispatch*.
#define FADF_VARIANT        0x0800    // An array of VARIANTs.
#define FADF_RESERVED    0xF0E8    // Bits reserved for future use.