VARIANT有一个变量vt, 类型为VARTYPE,指定了数据类型:比如:VT_I2,VT_I4,VT_R4,VT_R8等,分别表示short,long,float,double,
对应的值分别存在iVal,lVal,fltVal,dblVal中。
(1) VARIANT的初始化
VARIANT va;
va.vt=VT_I4;
va.lVal=5;
或者
VARIANT va;
VariantInit(&va);
(2) VARIANT的拷贝 VariantCopy
VARIANT va;
VARIANT va2;
va.vt=VT_I4;
va.lVal=5;
VariantCopy(&va2,&va);
这样就将 va的内容,拷贝到va2了。它会根据不同的数据类型,执行深拷贝或者浅拷贝。
(3)VARIANT的销毁 VariantClear
VariantClear(&va);
CComVariant
CComVariant类是ATL 对VARIANT数据类型的一个包装,它内部维护了一个VARIANT数据结构。所以我们可以很方便的在大多数情况下用CComVariant来替代VARIANT。
(1) CComVariant 的构造
有很多构造函数,比如:
默认构造函数:CComVariant()
BYTE构造函数:CComVariant(BYTE nSrc)
short构造函数:CComVariant(short nSrc)
long 构造函数:CComVariant(long nSrc, VARTYPE=VT_I4)
bool 构造函数:CComVariant(bool nSrc)
这个函数有点特别,如果是true,那么boolVal会被赋值为ATL_VARIANT_TRUE,否则, 会被赋值为ATL_VARIANT_FALSE
IDispatch* 构造函数: CComVariant(IDispatch *)
IUnknown*构造函数: CComVariant(IUnknown *)
VARIANT构造函数: CComVariant(const VARIANT *var)
本身构造函数: CComVariant(const CComVariant & varSrc)
在使用CComVariant(const VARIANT *var)的时候,要注意一定要先初始化var参数,否则会导致 CComVariant被创建为 VT_ERROR
比如下面的代码, 导致 CComVariant被创建为 VT_ERROR
void fuck()
{
VARIANT vt;
CComVariant ccv(&vt);
}
跟BSTR相关的构造函数:
CComVariant(const CComBSTR & bstrSrc)
CComVariant(LPCOLESTR lpszSrc)
CComVariant(LPCSTR lpszSrc)
这三个构造函数,如果不能顺利的构建BSTR内存,那么也会将CComVariant构建为
VT_ERROR.
上面三个构造函数,只有第一个能够正确的处理含有NULL的字符串,下面的两个将被NULL给截断,原因就是BSTR的构建过程中,会将NULL当做结束符。
(2)CComVariant的赋值
赋值跟构造函数类似,也是很多类似的赋值函数。
(3)Clear函数
如果要释放CComVariant,那么需要调用Clear函数,但是在CComVariant的析构函数中,Clear会被自动的调用,所以一般不需要自己去手动调用Clear函数。
(4)Copy函数
Copy将CComVariant的内容,拷贝到一个VARIANT
VARIANT vt;
long i=5;
CComVariant cvt(i);
cvt.Copy(&vt);
(5) Detach函数
如果想把CComVariant的实例内容的管理权交给VARIANT管理时,使用Detach函数。这个时候,CComVariant将不再自动管理内容。
在一个方法里面,如果要用Detach设置一个VARIANT的输出参数时候,记得一定要初始化VARIANT参数,因为在Detach的时候,CComVariant会去销毁清除指定的VARIANT,这个时候,如果VARIANT没有被初始化,那么就很可能会抛出异常。
应该用下面的代码处理:
void getVariant(VARIANT * poutVar)
{
VariantInit(poutVar);
//或者
poutVar->vt=VT_EMPTY;
//假定ccvar是一个被正确初始化和赋值的CComVariant
ccvar->Detach(poutVar);
}
(6) Attach函数
Attach可以让一个CComVariant获得VARIANT的所以权,全面接管所有权。
VARIANT vt;
vt.vt=VT_BSTR;
vt.bstrVal=::SysAllocString("Hello VARIANT");
CComVariant ccv;
ccv.Attach(&vt);
这样,CComVariant就接管了 bstr,而 vt不再拥有bstr了,可以不管vt了。
最后,如果给一个COM方法传递VARIANT,以及如何从一个方法获得VARIANT呢?
//设置
void SetVar(VARIANT * var)
{
CComVariant ccc;
ccc=var;
//这里利用的是 VARIANT赋值函数
}
//获得
void GetVar(VARIANT * var)
{
VariantInit(var);
CComVariant ccc;
ccc.Copy(var);
//或者
ccc.Detach(var);
}