The VARIANT Type

No doubt you've noticed the VARIANT type used in both Automation client and component functions in the previous example. VARIANT is an all-purpose data type that IDispatch::Invoke uses to transmit parameters and return values. The VARIANT type is the natural type to use when exchanging data with VBA. Let's look at a simplified version of the VARIANT definition in the Windows header files.

 struct tagVARIANT {     VARTYPE vt; // unsigned short integer type code     WORD wReserved1, wReserved2, wReserved3;     union {         short      iVal;                 // VT_I2  short integer         long       lVal;                 // VT_I4  long integer         float      fltVal;               // VT_R4  4-byte float         double     dblVal;               // VT_R8  8-byte IEEE float         DATE       date;                 // VT_DATE stored as dbl                                          //  date.time         CY         vtCY                  // VT_CY 64-bit integer         BSTR       bstrVal;              // VT_BSTR         IUnknown*  punkVal;              // VT_UNKNOWN         IDispatch* pdispVal;             // VT_DISPATCH         short*     piVal;                // VT_BYREF | VT_I2         long*      plVal;                // VT_BYREF | VT_I4         float*     pfltVal;              // VT_BYREF | VT_R4         double*    pdblVal;              // VT_BYREF | VT_R8         DATE*      pdate;                // VT_BYREF | VT_DATE         CY*        pvtCY;                // VT_BYREF | VT_CY         BSTR*      pbstrVal;             // VT_BYREF | VT_BSTR     } }; typedef struct tagVARIANT VARIANT; 

As you can see, the VARIANT type is a C structure that contains a type code vt, some reserved bytes, and a big union of types that you already know about. If vt is VT_I2, for example, you would read the VARIANT's value from iVal, which contains a 2-byte integer. If vt is VT_R8, you would read this value from dblVal, which contains an 8-byte real value.

A VARIANT object can contain actual data or a pointer to data. If vt has the VT_BYREF bit set, you must access a pointer in piVal, plVal, and so on. Note that a VARIANT object can contain an IUnknown pointer or an IDispatch pointer. This means that you can pass a complete COM object using an Automation call, but if you want VBA to process that object, its class should have an IDispatch interface.

Strings are special. The BSTR type is yet another way to represent character strings. A BSTR variable is a pointer to a zero-terminated character array with a character count in front. A BSTR variable could, therefore, contain binary characters, including zeros. If you had a VARIANT object with vt = VT_BSTR, memory would look like this.

Because the string has a terminating 0, you can use bstrVal as though it were an ordinary char pointer, but you have to be very, very careful about memory cleanup. You can't simply delete the string pointer, because the allocated memory begins with the character count. Windows provides the SysAllocString and SysFreeString functions for allocating and deleting BSTR objects.

SysAllocString is another COM function that takes a wide string pointer as a parameter. This means that all BSTRs contain wide characters, even if you haven't defined _UNICODE. Be careful.

Windows supplies some useful functions for VARIANTs, including those shown in the following table. If a VARIANT contains a BSTR, these functions ensure that memory is allocated and cleared properly. The VariantInit and VariantClear functions set vt to VT_EMPTY. All the variant functions are global functions and take a VARIANT* parameter.

Function Description
VariantInit Initializes a VARIANT
VariantClear Clears a VARIANT
VariantCopy Frees memory associated with the destination VARIANT and copies the source VARIANT
VariantCopyInd Frees the destination VARIANT and performs any indirection necessary to copy the source VARIANT
VariantChangeType Changes the type of the VARIANT


Programming Microsoft Visual C++
Programming Microsoft Visual C++
ISBN: 1572318570
EAN: 2147483647
Year: 1997
Pages: 332

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net