windows的VARIANT本质是含有类型信息的union。其结构如下:
typedef struct tagVARIANT VARIANT;
struct tagVARIANT
{
union
{
struct __tagVARIANT
{
VARTYPE vt; // typedef unsigned short VARTYPE
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
LONGLONG
llval;
// VT_I8.
LONG
lVal;
// VT_I4.
BYTE
bVal;
// VT_UI1.
SHORT
iVal;
// VT_I2.
FLOAT
fltVal;
// VT_R4.
DOUBLE
dblVal;
// VT_R8.
VARIANT_BOOL boolVal; // VT_BOOL.
_VARIANT_BOOL bool;
SCODE
scode; // VT_ERROR.
CY
cyVal; // VT_CY.
DATE
date; // VT_DATE.
BSTR
bstrVal; // VT_BSTR.
IUnknown * punkVal; // VT_UNKNOWN.
IDispatch
* pdispVal; // VT_DISPATCH.
SAFEARRAY * parray; // VT_ARRAY|*.
BYTE
* pbVal; // VT_BYREF|VT_UI1.
SHORT
* piVal; // VT_BYREF|VT_I2.
LONG
* plVal; // VT_BYREF|VT_I4.
LONGLONG * pllVal; // VT_BYREF|VT_I8.
FLOAT
* pfltVal; // VT_BYREF|VT_R4.
DOUBLE
* pdblVal; // VT_BYREF|VT_R8.
VARIANT_BOOL * pboolVal; // VT_BYREF|VT_BOOL.
_VARIANT_BOOL * pbool;
SCODE * pscode; // VT_BYREF|VT_ERROR.
CY
* pcyVal; // VT_BYREF|VT_CY.
DATE
* pdate; // VT_BYREF|VT_DATE.
BSTR
* pbstrVal; // VT_BYREF|VT_BSTR.
IUnknown ** ppunkVal; // VT_BYREF|VT_UNKNOWN.
IDispatch
** ppdispVal; // VT_BYREF|VT_DISPATCH.
SAFEARRAY ** pparray; // VT_BYREF|VT_ARRAY.
VARIANT
* pvarVal; // VT_BYREF|VT_VARIANT.
PVOID
* byref; // Generic ByRef.
CHAR
cVal; // VT_I1.
USHORT
uiVal; // VT_UI2.
ULONG
ulVal; // VT_UI4.
ULONGLONG ullVal; // VT_UI8.
INT
intVal; // VT_INT.
UINT
uintVal; // VT_UINT.
DECIMAL * pdecVal // VT_BYREF|VT_DECIMAL.
CHAR * pcVal; // VT_BYREF|VT_I1.
USHORT * puiVal; // VT_BYREF|VT_UI2.
ULONG * pulVal; // VT_BYREF|VT_UI4.
ULONGLONG * pullVal; // VT_BYREF|VT_UI8.
INT
* pintVal; // VT_BYREF|VT_INT.
UINT
* puintVal; // VT_BYREF|VT_UINT.
struct __tagBRECORD
{
PVOID pvRecord;
IRecordInfo *pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};
enum VARENUM
{
VT_EMPTY
= 0,
VT_NULL
= 1,
VT_I2
= 2,
VT_I4
= 3,
VT_R4
= 4,
VT_R8
= 5,
VT_CY
= 6,
VT_DATE
= 7,
VT_BSTR
= 8,
VT_DISPATCH
= 9,
VT_ERROR
= 10,
VT_BOOL
= 11,
VT_VARIANT
= 12,
VT_UNKNOWN
= 13,
VT_DECIMAL
= 14,
VT_I1
= 16,
VT_UI1
= 17,
VT_UI2
= 18,
VT_UI4
= 19,
VT_I8
= 20,
VT_UI8
= 21,
VT_INT
= 22,
VT_UINT
= 23,
VT_VOID
= 24,
VT_HRESULT
= 25,
VT_PTR
= 26,
VT_SAFEARRAY
= 27,
VT_CARRAY
= 28,
VT_USERDEFINED
= 29,
VT_LPSTR
= 30,
VT_LPWSTR
= 31,
VT_RECORD
= 36,
VT_INT_PTR
= 37,
VT_UINT_PTR
= 38,
VT_FILETIME
= 64,
VT_BLOB
= 65,
VT_STREAM
= 66,
VT_STORAGE
= 67,
VT_STREAMED_OBJECT
= 68,
VT_STORED_OBJECT
= 69,
VT_BLOB_OBJECT
= 70,
VT_CF
= 71,
VT_CLSID
= 72,
VT_VERSIONED_STREAM
= 73,
VT_BSTR_BLOB
= 0xfff,
VT_VECTOR
= 0x1000,
VT_ARRAY
= 0x2000,
VT_BYREF
= 0x4000,
VT_RESERVED
= 0x8000,
VT_ILLEGAL
= 0xffff,
VT_ILLEGALMASKED
= 0xfff,
VT_TYPEMASK
= 0xfff
} ;
借助这一结构,使得VARIANT可以容纳各种各样的数据类型。当然,这些类型都是静态的。
由于VARIANT只是简单的结构,因此使用很简单.给VARIANT变量的赋值的时候,首先给vt成员赋值,指定类型,再对union中相同数据类型的变量赋值,
VARIANT va;
int a=2001;
va.vt=VT_I4; // 指明整型数据
va.lVal=a; // 赋值
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg)进行初始化。
为了使VAIRANT使用更方便,微软对其进行了封装,封装后的类有_variant_t和COleVariant. 可以进行直接赋值,不再需要指定类型。
例如:
_variant_t val(long(1));
COleVariant val(FALSE);
更多资料,请参考msdn对这两个类的介绍。