一:为什么会有这个?

  目前,计算机语言有很多(大哥,为什么不能就那么一样呢?),如C++、Java,此外还有JavaScript、VBScript等脚本语言,它们自立门派,各自维护自己的数据类型。

  C++是一种强类型语言,即C++中的某个变量,在使用时类型已经确定,C++中的变量都会被翻译成准确的内存地址和大小,如果类型不确定是不可能处理的。当使用C++这样强类型的语言来读取数据库或者与其他语言之间来交换数据时,它很有可能不知道获取到的数据的具体类型,这个时候必须借助于变体类型读取数据。VARIANT数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。




二:VARIANT的定义

  在我的windows C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include下OAIdl.h有这个东东的定义:

typedef /* [wire_marshal] */ struct tagVARIANT VARIANT;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;} ;
typedef VARIANT *LPVARIANT;typedef VARIANT VARIANTARG;typedef VARIANT *LPVARIANTARG;

variant

看,就是这个东西。太难看了,下面是一个文件简化的让人看的:

struct tagVARIANT
{union {VARTYPE vt;WORD wReserved1;WORD wReserved2;WORD wReserved3;union {LONG lVal;BYTE bVal;SHORT iVal;FLOAT fltVal;DOUBLE dblVal;VARIANT_BOOL boolVal;DATE date;BSTR bstrVal;SAFEARRAY *parray;VARIANT *pvarVal;};};
};

简化

  VARIANT数据结构包含两个域(如果不考虑保留的域)。vt域描述了第二个域的数据类型。为了使多种类型能够在第二个域中出现,定义了一个联合结构。所以,第二个域的名称随着vt域中输入值的不同而改变。下面是同一个文件的里面的东东,这个东西是vt域可以赋哪些值及这些值代表什么变量类型:

/* VARIANT STRUCTURE**  VARTYPE vt;*  WORD wReserved1;*  WORD wReserved2;*  WORD wReserved3;*  union {*    LONGLONG       VT_I8*    LONG           VT_I4*    BYTE           VT_UI1*    SHORT          VT_I2*    FLOAT          VT_R4*    DOUBLE         VT_R8*    VARIANT_BOOL   VT_BOOL*    SCODE          VT_ERROR*    CY             VT_CY*    DATE           VT_DATE*    BSTR           VT_BSTR*    IUnknown *     VT_UNKNOWN*    IDispatch *    VT_DISPATCH*    SAFEARRAY *    VT_ARRAY*    BYTE *         VT_BYREF|VT_UI1*    SHORT *        VT_BYREF|VT_I2*    LONG *         VT_BYREF|VT_I4*    LONGLONG *     VT_BYREF|VT_I8*    FLOAT *        VT_BYREF|VT_R4*    DOUBLE *       VT_BYREF|VT_R8*    VARIANT_BOOL * VT_BYREF|VT_BOOL*    SCODE *        VT_BYREF|VT_ERROR*    CY *           VT_BYREF|VT_CY*    DATE *         VT_BYREF|VT_DATE*    BSTR *         VT_BYREF|VT_BSTR*    IUnknown **    VT_BYREF|VT_UNKNOWN*    IDispatch **   VT_BYREF|VT_DISPATCH*    SAFEARRAY **   VT_BYREF|VT_ARRAY*    VARIANT *      VT_BYREF|VT_VARIANT*    PVOID          VT_BYREF (Generic ByRef)*    CHAR           VT_I1*    USHORT         VT_UI2*    ULONG          VT_UI4*    ULONGLONG      VT_UI8*    INT            VT_INT*    UINT           VT_UINT*    DECIMAL *      VT_BYREF|VT_DECIMAL*    CHAR *         VT_BYREF|VT_I1*    USHORT *       VT_BYREF|VT_UI2*    ULONG *        VT_BYREF|VT_UI4*    ULONGLONG *    VT_BYREF|VT_UI8*    INT *          VT_BYREF|VT_INT*    UINT *         VT_BYREF|VT_UINT*  }*/

类型标识




三:使用例子

  看一个小例子就知道怎么用了:

#include <iostream>
#include <OAIdl.h>using namespace std;int main(void)
{VARIANT var;cout<<sizeof(VARIANT)<<endl;var.vt = VT_BOOL;        //boolvar.boolVal = true;cout<<var.boolVal<<endl;var.vt = VT_I4;        //longvar.lVal = 100;cout<<var.lVal<<endl;var.vt = VT_R8;        //doublevar.dblVal = 3.23;cout<<var.dblVal<<endl;cin.get();
}

C++例子

从中可以看到使用时,你要先指定这个variant是个什么玩意儿,然后给那个玩意儿赋值,输出的时候也要输出那个玩意儿的值,乖点总没错。输出:




四:还有一点

  在使用VARIANT的时候,经常会用到一些它给定的宏,这些宏可以很方便地对VARIANT指定类型及赋值,在我的 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include 下的oleauto.h里面就有:

// Declare variant access functions.#if __STDC__ || defined(NONAMELESSUNION)
#define V_UNION(X, Y)   ((X)->n1.n2.n3.Y)
#define V_VT(X)         ((X)->n1.n2.vt)
#define V_RECORDINFO(X) ((X)->n1.n2.n3.brecVal.pRecInfo)
#define V_RECORD(X)     ((X)->n1.n2.n3.brecVal.pvRecord)
#else
#define V_UNION(X, Y)   ((X)->Y)
#define V_VT(X)         ((X)->vt)
#define V_RECORDINFO(X) ((X)->pRecInfo)
#define V_RECORD(X)     ((X)->pvRecord)
#endif/* Variant access macros*/
#define V_ISBYREF(X)     (V_VT(X)&VT_BYREF)
#define V_ISARRAY(X)     (V_VT(X)&VT_ARRAY)
#define V_ISVECTOR(X)    (V_VT(X)&VT_VECTOR)
#define V_NONE(X)        V_I2(X)#define V_UI1(X)         V_UNION(X, bVal)
#define V_UI1REF(X)      V_UNION(X, pbVal)
#define V_I2(X)          V_UNION(X, iVal)
#define V_I2REF(X)       V_UNION(X, piVal)
#define V_I4(X)          V_UNION(X, lVal)
#define V_I4REF(X)       V_UNION(X, plVal)
#define V_I8(X)          V_UNION(X, llVal)
#define V_I8REF(X)       V_UNION(X, pllVal)
#define V_R4(X)          V_UNION(X, fltVal)
#define V_R4REF(X)       V_UNION(X, pfltVal)
#define V_R8(X)          V_UNION(X, dblVal)
#define V_R8REF(X)       V_UNION(X, pdblVal)
#define V_I1(X)          V_UNION(X, cVal)
#define V_I1REF(X)       V_UNION(X, pcVal)
#define V_UI2(X)         V_UNION(X, uiVal)
#define V_UI2REF(X)      V_UNION(X, puiVal)
#define V_UI4(X)         V_UNION(X, ulVal)
#define V_UI4REF(X)      V_UNION(X, pulVal)
#define V_UI8(X)         V_UNION(X, ullVal)
#define V_UI8REF(X)      V_UNION(X, pullVal)
#define V_INT(X)         V_UNION(X, intVal)
#define V_INTREF(X)      V_UNION(X, pintVal)
#define V_UINT(X)        V_UNION(X, uintVal)
#define V_UINTREF(X)     V_UNION(X, puintVal)#ifdef _WIN64
#define V_INT_PTR(X)        V_UNION(X, llVal)
#define V_UINT_PTR(X)       V_UNION(X, ullVal)
#define V_INT_PTRREF(X)     V_UNION(X, pllVal)
#define V_UINT_PTRREF(X)    V_UNION(X, pullVal)
#else
#define V_INT_PTR(X)        V_UNION(X, lVal)
#define V_UINT_PTR(X)       V_UNION(X, ulVal)
#define V_INT_PTRREF(X)     V_UNION(X, plVal)
#define V_UINT_PTRREF(X)    V_UNION(X, pulVal)
#endif#define V_CY(X)          V_UNION(X, cyVal)
#define V_CYREF(X)       V_UNION(X, pcyVal)
#define V_DATE(X)        V_UNION(X, date)
#define V_DATEREF(X)     V_UNION(X, pdate)
#define V_BSTR(X)        V_UNION(X, bstrVal)
#define V_BSTRREF(X)     V_UNION(X, pbstrVal)
#define V_DISPATCH(X)    V_UNION(X, pdispVal)
#define V_DISPATCHREF(X) V_UNION(X, ppdispVal)
#define V_ERROR(X)       V_UNION(X, scode)
#define V_ERRORREF(X)    V_UNION(X, pscode)
#define V_BOOL(X)        V_UNION(X, boolVal)
#define V_BOOLREF(X)     V_UNION(X, pboolVal)
#define V_UNKNOWN(X)     V_UNION(X, punkVal)
#define V_UNKNOWNREF(X)  V_UNION(X, ppunkVal)
#define V_VARIANTREF(X)  V_UNION(X, pvarVal)
#define V_ARRAY(X)       V_UNION(X, parray)
#define V_ARRAYREF(X)    V_UNION(X, pparray)
#define V_BYREF(X)       V_UNION(X, byref)#define V_DECIMAL(X)     V_UNION(X, decVal)
#define V_DECIMALREF(X)  V_UNION(X, pdecVal)#ifndef RC_INVOKED
#include <poppack.h>
#endif // RC_INVOKED#endif     // __OLEAUTO_H__

Variant宏

同样的目录wtypes.h下也有:

typedef unsigned short VARTYPE;/** VARENUM usage key,** * [V] - may appear in a VARIANT* * [T] - may appear in a TYPEDESC* * [P] - may appear in an OLE property set* * [S] - may appear in a Safe Array***  VT_EMPTY            [V]   [P]     nothing*  VT_NULL             [V]   [P]     SQL style Null*  VT_I2               [V][T][P][S]  2 byte signed int*  VT_I4               [V][T][P][S]  4 byte signed int*  VT_R4               [V][T][P][S]  4 byte real*  VT_R8               [V][T][P][S]  8 byte real*  VT_CY               [V][T][P][S]  currency*  VT_DATE             [V][T][P][S]  date*  VT_BSTR             [V][T][P][S]  OLE Automation string*  VT_DISPATCH         [V][T]   [S]  IDispatch **  VT_ERROR            [V][T][P][S]  SCODE*  VT_BOOL             [V][T][P][S]  True=-1, False=0*  VT_VARIANT          [V][T][P][S]  VARIANT **  VT_UNKNOWN          [V][T]   [S]  IUnknown **  VT_DECIMAL          [V][T]   [S]  16 byte fixed point*  VT_RECORD           [V]   [P][S]  user defined type*  VT_I1               [V][T][P][s]  signed char*  VT_UI1              [V][T][P][S]  unsigned char*  VT_UI2              [V][T][P][S]  unsigned short*  VT_UI4              [V][T][P][S]  unsigned long*  VT_I8                  [T][P]     signed 64-bit int*  VT_UI8                 [T][P]     unsigned 64-bit int*  VT_INT              [V][T][P][S]  signed machine int*  VT_UINT             [V][T]   [S]  unsigned machine int*  VT_INT_PTR             [T]        signed machine register size width*  VT_UINT_PTR            [T]        unsigned machine register size width*  VT_VOID                [T]        C style void*  VT_HRESULT             [T]        Standard return type*  VT_PTR                 [T]        pointer type*  VT_SAFEARRAY           [T]        (use VT_ARRAY in VARIANT)*  VT_CARRAY              [T]        C style array*  VT_USERDEFINED         [T]        user defined type*  VT_LPSTR               [T][P]     null terminated string*  VT_LPWSTR              [T][P]     wide null terminated string*  VT_FILETIME               [P]     FILETIME*  VT_BLOB                   [P]     Length prefixed bytes*  VT_STREAM                 [P]     Name of the stream follows*  VT_STORAGE                [P]     Name of the storage follows*  VT_STREAMED_OBJECT        [P]     Stream contains an object*  VT_STORED_OBJECT          [P]     Storage contains an object*  VT_VERSIONED_STREAM       [P]     Stream with a GUID version*  VT_BLOB_OBJECT            [P]     Blob contains an object *  VT_CF                     [P]     Clipboard format*  VT_CLSID                  [P]     A Class ID*  VT_VECTOR                 [P]     simple counted array*  VT_ARRAY            [V]           SAFEARRAY**  VT_BYREF            [V]           void* for local use*  VT_BSTR_BLOB                      Reserved for system use*/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} ;

枚举等

在调试的时候看到了这种难看的就按 Alt+G进入源文件看看是干啥的。

  下面是我看到的源码:

 1 DISPAPI KETAPITextBox::Copy( VARIANT *RHS )
 2 {
 3     ASSERT(m_spShape);
 4     VERIFY_IN_POINTER(RHS);
 5
 6     HRESULT hr = m_spShape->Copy();
 7     V_VT(RHS) = VT_BOOL;
 8     V_BOOL(RHS) = SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE;
 9
10     return hr;
11 }

从第7行看,V_VT(RHS) = VT_BOOL; 这句话就是把RHS指向的VARIANT的vt值赋成VT的bool类型,其实也就是 RHS->vt = VARIANT的bool 这个意思了,现在这个variant表示bool啦,懂了!

转载于:https://www.cnblogs.com/jiayith/p/3865058.html

C++ VARIANT 学习小记录相关推荐

  1. 神经网络学习小记录2——利用tensorflow构建循环神经网络(RNN)

    神经网络学习小记录2--利用tensorflow构建循环神经网络(RNN) 学习前言 RNN简介 tensorflow中RNN的相关函数 tf.nn.rnn_cell.BasicLSTMCell tf ...

  2. 神经网络学习小记录52——Pytorch搭建孪生神经网络(Siamese network)比较图片相似性

    神经网络学习小记录52--Pytorch搭建孪生神经网络(Siamese network)比较图片相似性 学习前言 什么是孪生神经网络 代码下载 孪生神经网络的实现思路 一.预测部分 1.主干网络介绍 ...

  3. 神经网络学习小记录45——Keras常用学习率下降方式汇总

    神经网络学习小记录45--Keras常用学习率下降方式汇总 2020年5月19日更新 前言 为什么要调控学习率 下降方式汇总 1.阶层性下降 2.指数型下降 3.余弦退火衰减 4.余弦退火衰减更新版 ...

  4. 神经网络学习小记录58——Keras GhostNet模型的复现详解

    神经网络学习小记录58--Keras GhostNet模型的复现详解 学习前言 什么是GhostNet模型 源码下载 GhostNet模型的实现思路 1.Ghost Module 2.Ghost Bo ...

  5. 神经网络学习小记录39——MobileNetV3(small)模型的复现详解

    神经网络学习小记录39--MobileNetV3(small)模型的复现详解 学习前言 什么是MobileNetV3 代码下载 large与small的区别 MobileNetV3(small)的网络 ...

  6. 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...

  7. 神经网络学习小记录-番外篇——常见问题汇总

    神经网络学习小记录-番外篇--常见问题汇总 前言 问题汇总 1.下载问题 a.代码下载 b. 权值下载 c. 数据集下载 2.环境配置问题 a.20系列所用的环境 b.30系列显卡环境配置 c.CPU ...

  8. 神经网络学习小记录50——Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台

    神经网络学习小记录50--Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思 ...

  9. 神经网络学习小记录17——使用AlexNet分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录17--使用AlexNet分类模型训练自己的数据(猫狗数据集) 学习前言 什么是AlexNet模型 训练前准备 1.数据集处理 2.创建Keras的AlexNet模型 开始训练 1. ...

最新文章

  1. swift 浮点型字符串的运算
  2. ddos攻击python_Python基于http的ddos攻击代码
  3. STM32F103的USART1和USART2的TX和RX所对应的分别是那个引脚?
  4. Ado.Net实现简易(省、市、县)三级联动查询,还附加Access数据
  5. 各IO 模型对比与总结
  6. 天池 在线编程 高效作业处理服务(01背包DP)
  7. memoryTraining记忆训练小游戏
  8. Python帮你把B站上喜欢的视频下载下来
  9. Leetcode题目:Reverse String
  10. Vivaldi for Mac(极速浏览器)支持m1
  11. [译] TensorFlow 教程 #09 - 视频数据
  12. 蓝桥杯C语言---基础练习
  13. Adobe软件中PS、PR、AE、AI软件如何安装【附软件下载】
  14. android组件搭配
  15. JAVA毕设项目社区电商平台系统(java+VUE+Mybatis+Maven+Mysql)
  16. Linux-菜鸟入门自学 (二)
  17. 根因定位FluxRank论文背景说明
  18. js判断两个字符串相等问题
  19. springboot 秒杀系统(二)redis
  20. LocalStorage存储对象

热门文章

  1. 特斯拉纯视觉FSD版本Bug频发!马斯克:不认真测试的车主就取消资格
  2. 只用嘴唇动一动,AI就能合成语音,效果自然流畅看不出破绽
  3. 4行代码再现《黑客帝国》数字雨,在终端实现的那种
  4. Momenta完全无人驾驶首次曝光!城区道路混行无接管,遭遇逆行也不怕,特斯拉Waymo路线二合一...
  5. 重置SQLSERVER表的自增列,让自增列重新计数
  6. UAVStack的慢SQL数据库监控功能及其实现
  7. JavaScript创建元素的三种方法特点及对元素的操作
  8. handlebars.js 用 br替换掉 内容的换行符
  9. ios开发学习--cocos2d(cocos2d)效果源码分享--系列教程
  10. [转] SAAS, PAAS, IAAS