关于COM中变体类型VARIANT
从com的设计初衷来讲,要达到跨语言的目的,但是c++啊,java,python,pascal什么的都是有自己的数据类型的,设计这个变体类型VARIANT就是为了达到这个目的,之所以称之为变体类型是因为它的类型不是固定的,基本上可以表示COM里面的任何基本类型和常见接口指针,从c++的本质来讲,VARIANT类型就是一个结构体,该结构体中有一个成员是表示该变量到底是个什么变量,也就是应该把这个表示数据的部分解释成一个什么东东,实际的数据是存在结构体的一个联合体成员中的。
且看它在C++中的定义:
VARIANT 数据类型在文件OAIDL.IDL中定义如下:
struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
ULONGLONG ullVal; /* VT_UI8 */
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; /* (obsolete) */
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; /* (obsolete) */
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 */
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; /* VT_RECORD */
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};
其中wReserved1,wReserved2,wReserved3是保留域,暂时可以不看,vt域表示下面的联合体域的数据类型,分别怎么表示可以看联合体中每个成员后面的注释,其实也是一个枚举类型,如下:
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类型的时候就要分两步了,首先赋值类型vt域,然后给联合体域赋值,此时应该注意的是,最好使用正确的数据域,否则代码会晦涩难懂,如下:
VARIANT_BOOL bValue = VARIANT_TRUE;
VARIANT vParam;
vParam.vt = VT_BYREF | VT_BOOL;
vParam.pboolVal = &bValue;
如果觉得这么使用难用的话,可以使用包装类,CComVariant、COleVariant、_variant_t。
Invoke方法中有个参数类型是DISPPARAMS,这个也是一个结构体,定义如下:
typedef struct tagDISPPARAMS
{
/* [size_is] */ VARIANTARG *rgvarg;
/* [size_is] */ DISPID *rgdispidNamedArgs;
UINT cArgs;
UINT cNamedArgs;
}
DISPPARAMS;
cArgs表示rgvarg数组的长度,其中VARIANTARG实际就是VARIANT类型,这里是一个VARIANT类型的数组,rgvarg指向这个数组的第一个元素。
[END]
关于COM中变体类型VARIANT相关推荐
- 变体类型Variant
变体类型Variant,能够在运行期间动态的改变类型.变体类型能支持所有简单的数据类型,如整型.浮点.字符串.布尔型.日期时间.货币及OLE自动化对象等,不能够表达Object Pascal对象. 1 ...
- VARIANT变体类型数据
2019独角兽企业重金招聘Python工程师标准>>> 特殊 Variant 是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据.Variant ...
- C++变体数据类型—— VARIANT
百度百科: Variant 音标 Phonetic symbol [] 词性及解释 Part of speech and defination n. 变体, 异体 a. 不同的, 有差别的 [计] 变 ...
- Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换、变体类型常用的函数)...
来源:http://blog.csdn.net/xiongmao000738/article/details/6863988 一.变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型: ...
- SegeX SgxVariantArrayT:VC封装支持多维数组的变体类型(VRIANT 、SafeArray)(附免费免积分源代码)
----哆啦刘小洋 原创,转载需说明出处 2023-01-04 SgxVariantArrayT:支持多维数组的变体类型 1 简介 2 方法原理 2.1 继承于_variant_t 2.2 模板类型到 ...
- c语言中结构体类型只有,C语言中main()函数不要返回结构体类型(求助)
大家先看一下这段程序: #include typedef unsigned char bool; typedef struct _person person; struct _person { boo ...
- c语言中结构体类型定义的函数指针,结构体中定义函数指针
结构体指针变量的定义 定义结构体变量的一般形式如下:形式1:先定义结构体类型,再定义变量struct 结构体标识符{ 成员变量列表;-};struct 结构体标识符 *指针变量名;变量初始化:stru ...
- 自定义Flutter资源变体(variant)
Flutter目前没有支持到像andrid一样自动获取对应环境的变体资源,代码区分多语言取图片资源麻烦且代码可读性不高,为此封装了一个简单的ImageProvider 用来自动匹配资源 . 先讲下用法 ...
- php variant 数组,php – 如何将8209数组对象变体转换为VT_VARIANT
我正在调用一个COM对象方法,该方法在我的PHP代码中返回8209类型的数组变量对象. $com_VArray = $com_Object->objectMethod; //Is a 8209 ...
最新文章
- java通过ftp方式上传_通过FTP以Java方式上传文件
- 学生党如何拿到阿里技术offer:《阿里面试(成功)》
- 在内地城区经济发展中冒头,长沙雨花是如何做到的?
- 优秀的java代码_像这样写,Java菜鸟也能写出牛逼的代码
- matlab能力处理,书+程序《MATLAB图像处理:能力提高与应用案例》赵小川
- Ontheinternet的深圳论坛
- 笔试算法题(26):顺时针打印矩阵 求数组中数对差的最大值
- 线性回归 php,PHP实现简单线性回归之数学库的重要性
- docker 远程连接 文件看不到_Java 开发提升十倍生产力:IDEA 远程一键部署 Spring Boot 到 Docker...
- Jmeter入门6 参数化—CSV Data Set Config 通过文件导入数据
- django ----CBV中加装饰器
- [转载]Qt之模型/视图(实时更新数据)
- JS中的逻辑运算符、||,位运算符|,
- MySQL DBA教程:Mysql性能优化之缓存参数优化
- Spring(十六)之MVC框架
- 奶瓶(beini)破解无线密码流程:安装、抓包、从虚拟机(VMware)拷贝握手包(拷贝到硬盘、U盘)、跑包...
- 初学计算机,我在疑惑些什么?
- Oracle的软解析(soft prase)和硬解析(hard prase)及绑定变量
- Java泛型进阶篇: 无界通配符、上界通配符以及下界通配符
- 2013-04《信息资源管理 02378》真卷解析,逐题解析+背诵技巧