从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相关推荐

  1. 变体类型Variant

    变体类型Variant,能够在运行期间动态的改变类型.变体类型能支持所有简单的数据类型,如整型.浮点.字符串.布尔型.日期时间.货币及OLE自动化对象等,不能够表达Object Pascal对象. 1 ...

  2. VARIANT变体类型数据

    2019独角兽企业重金招聘Python工程师标准>>> 特殊 Variant 是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据.Variant ...

  3. C++变体数据类型—— VARIANT

    百度百科: Variant 音标 Phonetic symbol [] 词性及解释 Part of speech and defination n. 变体, 异体 a. 不同的, 有差别的 [计] 变 ...

  4. Delphi 变体类型(Variant)的介绍(流与变体类型的相互转换、变体类型常用的函数)...

    来源:http://blog.csdn.net/xiongmao000738/article/details/6863988 一.变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型: ...

  5. SegeX SgxVariantArrayT:VC封装支持多维数组的变体类型(VRIANT 、SafeArray)(附免费免积分源代码)

    ----哆啦刘小洋 原创,转载需说明出处 2023-01-04 SgxVariantArrayT:支持多维数组的变体类型 1 简介 2 方法原理 2.1 继承于_variant_t 2.2 模板类型到 ...

  6. c语言中结构体类型只有,C语言中main()函数不要返回结构体类型(求助)

    大家先看一下这段程序: #include typedef unsigned char bool; typedef struct _person person; struct _person { boo ...

  7. c语言中结构体类型定义的函数指针,结构体中定义函数指针

    结构体指针变量的定义 定义结构体变量的一般形式如下:形式1:先定义结构体类型,再定义变量struct 结构体标识符{ 成员变量列表;-};struct 结构体标识符 *指针变量名;变量初始化:stru ...

  8. 自定义Flutter资源变体(variant)

    Flutter目前没有支持到像andrid一样自动获取对应环境的变体资源,代码区分多语言取图片资源麻烦且代码可读性不高,为此封装了一个简单的ImageProvider 用来自动匹配资源 . 先讲下用法 ...

  9. php variant 数组,php – 如何将8209数组对象变体转换为VT_VARIANT

    我正在调用一个COM对象方法,该方法在我的PHP代码中返回8209类型的数组变量对象. $com_VArray = $com_Object->objectMethod; //Is a 8209 ...

最新文章

  1. java通过ftp方式上传_通过FTP以Java方式上传文件
  2. 学生党如何拿到阿里技术offer:《阿里面试(成功)》
  3. 在内地城区经济发展中冒头,长沙雨花是如何做到的?
  4. 优秀的java代码_像这样写,Java菜鸟也能写出牛逼的代码
  5. matlab能力处理,书+程序《MATLAB图像处理:能力提高与应用案例》赵小川
  6. Ontheinternet的深圳论坛
  7. 笔试算法题(26):顺时针打印矩阵 求数组中数对差的最大值
  8. 线性回归 php,PHP实现简单线性回归之数学库的重要性
  9. docker 远程连接 文件看不到_Java 开发提升十倍生产力:IDEA 远程一键部署 Spring Boot 到 Docker...
  10. Jmeter入门6 参数化—CSV Data Set Config 通过文件导入数据
  11. django ----CBV中加装饰器
  12. [转载]Qt之模型/视图(实时更新数据)
  13. JS中的逻辑运算符、||,位运算符|,
  14. MySQL DBA教程:Mysql性能优化之缓存参数优化
  15. Spring(十六)之MVC框架
  16. 奶瓶(beini)破解无线密码流程:安装、抓包、从虚拟机(VMware)拷贝握手包(拷贝到硬盘、U盘)、跑包...
  17. 初学计算机,我在疑惑些什么?
  18. Oracle的软解析(soft prase)和硬解析(hard prase)及绑定变量
  19. Java泛型进阶篇: 无界通配符、上界通配符以及下界通配符
  20. 2013-04《信息资源管理 02378》真卷解析,逐题解析+背诵技巧

热门文章

  1. vs2017和vs2019专业版和企业版
  2. 愿你学会优雅地控制自己的情绪
  3. win10系统 - U盘启动盘制作教程
  4. Python3.10.2安装教程
  5. MySQL架构介绍(一)
  6. 槛外人观察 :语义和语用
  7. 电脑最大支持的内存是多少
  8. 港片怀旧:《鹰爪铁布衫》(1)
  9. Arduino控制RGB灯(WS2812B)
  10. 【基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯】