Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3404297
  • 博文数量: 754
  • 博客积分: 10132
  • 博客等级: 上将
  • 技术积分: 7780
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-14 23:36
文章分类

全部博文(754)

文章存档

2012年(3)

2011年(39)

2010年(66)

2009年(167)

2008年(479)

我的朋友

分类: 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
BSTR x = SysAllocString(L"Hello");
VARIANT myVariant;
myVariant.vt = VT_BSTR;
myVariant.bstrVal = x;
SysFreeString(x);

//Create a CString and change it to a variant;
CString myCString(_T("My String"));
CString mySecondString;


//This is required to use the T2COLE macro.
USES_CONVERSION;



BSTR y = SysAllocString(T2COLE(myCString));
myVariant.bstrVal = y;
mySecondString = y;
SysFreeString(y);


//Create two BSTRs and add them.
BSTR a = SysAllocString(L"One two ");
BSTR b = SysAllocString(L"three four.");
_bstr_t my_bstr_t(a, TRUE);
my_bstr_t += b;
myVariant.bstrVal = my_bstr_t;
// or
myVariant.bstrVal = _bstr_t(a, FALSE) + b;

//Change a bstr to a CString.
CString ANewString(b);
//or if CString already exists.
myCString = b;

//Use of CComBSTR
CComBSTR myCComBSTR(L"Hello");
myCComBSTR.Append(L", how are you?");
VARIANT varFromCCom;
varFromCCom.vt = VT_BSTR;
varFromCCom.bstrVal = myCComBSTR;
阅读(4227) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~