分类: WINDOWS
2010-09-13 17:08:42
在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:
struct tagVARIANT {
VARTYPE vt;
union {
short iVal; // VT_I2.
long lVal; // VT_I4.
float fltVal; // VT_R4.
double dblVal; // VT_R8.
DATE date; // VT_DATE.
BSTR bstrVal; // VT_BSTR.
…
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.
BSTR * pbstrVal; // VT_BYREF|VT_BSTR.
};
};
显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。例如,如果vt为VT_I2,那么我们可以从iVal中读出VARIANT的值。同样,当给一个VARIANT变量赋值时,也要先指明其类型。例如:
VARIANT va;
:: VariantInit(&va); // 初始化
int a = 2002;
va.vt = VT_I4; // 指明long数据类型
va.lVal = a; // 赋值
为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:
VariantInit —— 将变量初始化为VT_EMPTY;
VariantClear —— 消除并初始化VARIANT;
VariantChangeType —— 改变VARIANT的类型;
VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。
COleVariant类是对VARIANT结构的封 装。它的构造函数具有极为强大大的功能,当对象构造时首先调用VariantInit进行初始化,然后根据参数中的标准类型调用相应的构造函数,并使用 VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函数就会被自动调用,由于析构函数调用了 VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与VARIANT类型转换中为我们提供极大的 方便。例如下面的代码:
COleVariant v1("This is a test"); // 直接构造
COleVariant v2 = "This is a test";
// 结果是VT_BSTR类型,值为"This is a test"
COleVariant v3((long)2002);
COleVariant v4 = (long)2002;
// 结果是VT_I4类型,值为2002
_variant_t是一个用于COM的VARIANT类,它的功能与COleVariant相似。不过在Visual C++.NET的MFC应用程序中使用时需要在代码文件前面添加下列两句:
#include "comutil.h"
#pragma comment( lib, "comsupp.lib" )
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Ackarlix/archive/2008/12/29/3640562.aspx
1. 直接使用VARIANT变量
a. 定义VARIANT变量
可以直接定义VARIANT类型的变量。
VARIANT val;
b. 初始化VARIANT变量
在使用VARIANT变量之前,一定要初始化。
VariantInit(&val);
c. 设置变量值
设置变量值前如果VARIANT变量中已经有值,先要清除原有数据。
VariantClear(&val);
val.vt = VT_I4; // 设置类型
val.lVal = 10; // 设置变量值
d. 清除VARIANT变量
在使用完VARIANT变量后,要清除变量,否则会发生内存泄漏。
VariantClear(&val);
e. 动态分配VARIANT变量
如果要动态分配VARIANT变量,应该使用标准的COM内存管理函数。
标准COM内存管理函数包括CoTaskMemAlloc、CoTaskMemFree和CoTaskMemRealloc。
VARIANT * pVal;
pVal = (VARIANT *)CoTaskMemAlloc(size_of(VARIANT));
VariantInit(pVal);
pVal->vt = VT_I4;
pVal->lVal = 10;
...
VariantClear(pVal);
CoTaskMemFree(pVal);
2. 通过CComVariant使用VARIANT变量
CComVariant是ATL对于VARIANT的简单包装。通过CComVariant可以更简单的使用VARIANT,而不必担心没有进行初始化或清除。如果没有特殊情况,应该尽量使用CComVariant而不要使用VARIANT。
以下是使用CComVariant的代码实例。
CComVariant Val;
Val.vt = VT_I4;
Val.lVal = 10;
// Val 不必清除
以下是使用CComVariant数组的例子。
CComVariant * pVal;
pVal = new CComVariant[10];
for (int i = 0; i < 10; ++i)
{
pVal[i].vt = VT_I4;
pVal[I].lVal = i + 1;
}
...
delete[] pVal;
VARIANT类型如何与其他字符串类型转换?
//Create a BSTR and assign it to a Variant