VARIANT的使用方法
VARIANT结构体主要是使用在COM(组件对象模型)中用于传递参数使用,它的存在主要是为了保持一个在COM参数传递方法的统一性,它几乎包含了所有普通常用类型的数据类型的传递,如整型,浮点型,布尔型等等,以及相应类型的指针类型,如整型指针。它的使用也比较方便。先来看看这个结构体它的结构:
typedef struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
LONGLONG llVal;
LONG lVal;
BYTE bVal;
SHORT iVal;
FLOAT fltVal;
DOUBLE dblVal;
VARIANT_BOOL boolVal;
_VARIANT_BOOL bool;
SCODE scode;
CY cyVal;
DATE date;
BSTR bstrVal;
IUnknown *punkVal;
IDispatch *pdispVal;
SAFEARRAY *parray;
BYTE *pbVal;
SHORT *piVal;
LONG *plVal;
LONGLONG *pllVal;
FLOAT *pfltVal;
DOUBLE *pdblVal;
VARIANT_BOOL *pboolVal;
_VARIANT_BOOL *pbool;
SCODE *pscode;
CY *pcyVal;
DATE *pdate;
BSTR *pbstrVal;
IUnknown **ppunkVal;
IDispatch **ppdispVal;
SAFEARRAY **pparray;
VARIANT *pvarVal;
PVOID byref;
CHAR cVal;
USHORT uiVal;
ULONG ulVal;
ULONGLONG ullVal;
INT intVal;
UINT uintVal;
DECIMAL *pdecVal;
CHAR *pcVal;
USHORT *puiVal;
ULONG *pulVal;
ULONGLONG *pullVal;
INT *pintVal;
UINT *puintVal;
struct __tagBRECORD {
PVOID pvRecord;
IRecordInfo *pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
} VARIANT, *LPVARIANT, VARIANTARG, *LPVARIANTARG;
这个结构体呢,有5个成员,分别是VARTYPE vt ,WORD wReserved1,WORD wReserved2,WORD wReserved3,和最后一个共用体。其中vt用以指明最后一个共用体中哪一个成员有效,wReserved1,wReserved2,wReserved3,这三个我们使用的时候不用管,系统保留,最后一个共用体根据vt的提示,对相应的成员进行值的存储。我们从两个不同的角度来理解,首先是使用VARIANT来存储参数,首先是声明一个这个结构体的对象,然后对对象的vt进行赋值,它可接受的值是一个枚举值,也就说只能在枚举这个范围内取值,比如我要用VARIANT传递一个整数,现在我对vt的赋值为VT_INT,这样就说明了我要使用这个结构体中共用体的整型变量,接着对INT变量进行赋值,赋我们要传递的值。这样就完成VARIANT的传递。现在我们从另外一个角度来理解VARIANT,刚才是我们对VARIANT对象进行赋值传递,现在我们是这个VARIANT对象的接收者,我们从参数中获得这个对象之后,我们首先检查这个结构体的vt成员,看它哪个类型的变量有效,比如就这个例子而言,检查到vt的值是VT_INT,因此,我直接去获取这个结构体中VT_INT所对应的变量,获取它的值。这样,我们从传递到使用两个角度来理解了VARIANT结构体,概括起来说,就是vt指明了我要传递的变量的类型,结构体中共用体的成员用来存储vt指明的类型的值。
下面来看看具体VARIANT结构体是如何使用赋值的,首先是第一种方法:
首先我们声明一个VARIANT结构体的对象vr1,然后使用VariantInit函数对其进行初始化,它的作用就是对vt赋VT_EMPTY,对别的变量值附空,否则就是一个随机值,这个过程和我们声明一个int变量一样,如果声明的时候不初始化,就是一个随机值。编程过程中,不管是指针还是什么变量,都应该在声明之后对其进行初始化。接着就是我赋VT_INT给vt,这里的V_VT就是代表要对vr1结构体中的vt成员进行幅值,接着对vr1中的INT成员赋值,这里的V_INT就是表示要对INT赋值,因此这里有一个规律,就是V_,它的后面加成员类型就可以对相应的成员赋值,而这里的成员类型有一个对照表,在文章的最后给出,比如,我要对BSTR成员赋值,我就用V_BSTR。这时候,就可以使用vr1了,使用完成之后,我们应该调用VariantClear函数,这个函数的作用就是将vt赋值为VT_EMPTY,以及释放使用这个结构体中的内存中的内容,如果是com对象,该函数是不会进行对象的release操作的,不管怎么样,我们都应该在使用完了VARIANT结构体之后,调用这个函数。
下面是第二种方法,原理和过程和地中方法类似,有一点微小的区别,就是VARIANT结构体的赋值上面来说,有点不同,如下:
接下来是字符串的操作,BSTR,我们不能直接将字符串传递一个VARIANT结构体对象,而是要用到函数SysAllocString,它的返回值就是一个BSTR,由它分配一个字符串,供VARIANT,对于为什么要这么做,可以自己查看MSDN COM的Automation那部分:
完成之后,我们还应该调用SysFreeString来释放由SysAllocString分配的内存。
另外,我们可以在类型与变量的对照表中发现,同一类型,对应了两种不同的变量,如,INT对应了变量有intVal和pintVal,其实这很简单,后者是指针性,如果要使用,说明我们赋值的对象是一个指针,如下:
最后给出类型与变量的对照表,如果是使用地中方法用V_加类型,就直接使用下表中VT_后的名称就可以了:
Member name | Description | |
---|---|---|
VT_EMPTY | Indicates that a value was not specified. | |
VT_NULL | Indicates a null value, similar to a null value in SQL. | |
VT_I2 | Indicates a short integer. | |
VT_I4 | Indicates a long integer. | |
VT_R4 | Indicates a float value. | |
VT_R8 | Indicates a double value. | |
VT_CY | Indicates a currency value. | |
VT_DATE | Indicates a DATE value. | |
VT_BSTR | Indicates a BSTR string. | |
VT_DISPATCH | Indicates an IDispatch pointer. | |
VT_ERROR | Indicates an SCODE. | |
VT_BOOL | Indicates a Boolean value. | |
VT_VARIANT | Indicates a VARIANT far pointer. | |
VT_UNKNOWN | Indicates an IUnknown pointer. | |
VT_DECIMAL | Indicates a decimal value. | |
VT_I1 | Indicates a char value. | |
VT_UI1 | Indicates a byte. | |
VT_UI2 | Indicates an unsignedshort. | |
VT_UI4 | Indicates an unsignedlong. | |
VT_I8 | Indicates a 64-bit integer. | |
VT_UI8 | Indicates an 64-bit unsigned integer. | |
VT_INT | Indicates an integer value. | |
VT_UINT | Indicates an unsigned integer value. | |
VT_VOID | Indicates a C style void. | |
VT_HRESULT | Indicates an HRESULT. | |
VT_PTR | Indicates a pointer type. | |
VT_SAFEARRAY | Indicates a SAFEARRAY. Not valid in a VARIANT. | |
VT_CARRAY | Indicates a C style array. | |
VT_USERDEFINED | Indicates a user defined type. | |
VT_LPSTR | Indicates a null-terminated string. | |
VT_LPWSTR | Indicates a wide string terminated by nullNothingnullptra null reference (Nothing in Visual Basic). | |
VT_RECORD | Indicates a user defined type. | |
VT_FILETIME | Indicates a FILETIME value. | |
VT_BLOB | Indicates length prefixed bytes. | |
VT_STREAM | Indicates that the name of a stream follows. | |
VT_STORAGE | Indicates that the name of a storage follows. | |
VT_STREAMED_OBJECT | Indicates that a stream contains an object. | |
VT_STORED_OBJECT | Indicates that a storage contains an object. | |
VT_BLOB_OBJECT | Indicates that a blob contains an object. | |
VT_CF | Indicates the clipboard format. | |
VT_CLSID | Indicates a class ID. | |
VT_VECTOR | Indicates a simple, counted array. | |
VT_ARRAY | Indicates a SAFEARRAY pointer. | |
VT_BYREF | Indicates that a value is a reference. |
更多详细信息,请参考msdn
或是有任何编程问题,到http://www.panshy.com提问或是查阅。
VARIANT的使用方法相关推荐
- java uuid静态方法_Java UUID的variant()方法和示例
java uuid静态方法 UUID类variant()方法 (UUID Class variant() method) variant() method is available in java.u ...
- Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换、变体类型常用的函数)...
来源:http://blog.csdn.net/xiongmao000738/article/details/6863988 一.变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型: ...
- API ‘variant.getAssemble()‘ is obsolete and has been replaced with ‘variant.getAssembleProvider()‘
Warning 日志 最近在做Android工程的架构升级,每次同步工程()都会报下面的告警信息: API 'variant.getAssemble()' is obsolete and has be ...
- 导出各种类型的文件的简单方法(暂时)
把html导出为excel或者word文档 [b]1.jsp页面简单导出[/b] 导出为excel: <% response.setContentType("application/v ...
- boost使用学习总结
boost常用库案例 http://www.cnblogs.com/wangkangluo1/archive/2011/07/19/2110746.html 1.boost::any boost::a ...
- ADO学习(九)如何阅读ADO文档
<ADO API参考>用VB的语法描述了ADO API的内容.但ADO程序员却使用着不同的编程语言,比如VB,VC++,VJ++.对此<ADO for VC++的语法索引> ...
- 在MFC中使用Cstring
此文介绍了关于MFC使用CString的资料,可一参考一下. 转自于VC知识库:http://www.vckbase.com/index.php/wv/829 通过阅读本文你可以学习如何有效地使用 C ...
- [转载]VC++程序员应当如何阅读ADO文档
<ADO API参考>用VB的语法描述了ADO API的内容.但ADO程序员却使用着不同的编程语言,比如VB,VC++,VJ++.对此<ADO for VC++的语法索引>提供 ...
- CString 操作指南
原著:Joseph M. Newcomer 翻译:littleloach 原文出处:codeproject:CString Management 通过阅读本文你可以学习如何有效地使用 CString. ...
最新文章
- 使用多个推理芯片需要仔细规划
- 在Python中实现SVM分类
- Oracle 11 密码永不过期
- 打分排序系统漫谈1 - 时间衰减
- [转载]matlab中控制mesh或者surf的颜色
- 今晚8点不见不散!余承东Vlog如此夸赞华为Mate30系列新机
- 大数据在智慧社区的作用有哪些
- 制作网页先写html还是css,制作网页是先学html还是css
- stl_algorithm算法之排序算法
- 错排公式的推导及应用
- 计算机网络技术与实验清华大学,清华大学计算机网络实验指示书.doc
- 《WinHex》误使用Ghost恢复系统恢复数据图文教程
- IB网卡驱动安装以及Infiniband连接带宽测试
- AdventureWorks 安装和配置[转自 微软msdn]
- lenovo启动热键_联想电脑如何进入U盘启动,按哪个快捷键?
- matlab centralize,智课雅思词汇---二十三、动词性后缀-ate-fy-ish-ize
- u盘工作表在计算机上打不开,U盘中无法打开的excel的解决办法
- linux中怎么连接wifi密码,Linux终端中连接WiFi的方法
- 【Windows系统】产品ID、设备ID等系统参数
- 软测(三)测试用例基本介绍