C++ VARIANT 学习小记录
一:为什么会有这个?
目前,计算机语言有很多(大哥,为什么不能就那么一样呢?),如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 学习小记录相关推荐
- 神经网络学习小记录2——利用tensorflow构建循环神经网络(RNN)
神经网络学习小记录2--利用tensorflow构建循环神经网络(RNN) 学习前言 RNN简介 tensorflow中RNN的相关函数 tf.nn.rnn_cell.BasicLSTMCell tf ...
- 神经网络学习小记录52——Pytorch搭建孪生神经网络(Siamese network)比较图片相似性
神经网络学习小记录52--Pytorch搭建孪生神经网络(Siamese network)比较图片相似性 学习前言 什么是孪生神经网络 代码下载 孪生神经网络的实现思路 一.预测部分 1.主干网络介绍 ...
- 神经网络学习小记录45——Keras常用学习率下降方式汇总
神经网络学习小记录45--Keras常用学习率下降方式汇总 2020年5月19日更新 前言 为什么要调控学习率 下降方式汇总 1.阶层性下降 2.指数型下降 3.余弦退火衰减 4.余弦退火衰减更新版 ...
- 神经网络学习小记录58——Keras GhostNet模型的复现详解
神经网络学习小记录58--Keras GhostNet模型的复现详解 学习前言 什么是GhostNet模型 源码下载 GhostNet模型的实现思路 1.Ghost Module 2.Ghost Bo ...
- 神经网络学习小记录39——MobileNetV3(small)模型的复现详解
神经网络学习小记录39--MobileNetV3(small)模型的复现详解 学习前言 什么是MobileNetV3 代码下载 large与small的区别 MobileNetV3(small)的网络 ...
- 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)
神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...
- 神经网络学习小记录-番外篇——常见问题汇总
神经网络学习小记录-番外篇--常见问题汇总 前言 问题汇总 1.下载问题 a.代码下载 b. 权值下载 c. 数据集下载 2.环境配置问题 a.20系列所用的环境 b.30系列显卡环境配置 c.CPU ...
- 神经网络学习小记录50——Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台
神经网络学习小记录50--Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思 ...
- 神经网络学习小记录17——使用AlexNet分类模型训练自己的数据(猫狗数据集)
神经网络学习小记录17--使用AlexNet分类模型训练自己的数据(猫狗数据集) 学习前言 什么是AlexNet模型 训练前准备 1.数据集处理 2.创建Keras的AlexNet模型 开始训练 1. ...
最新文章
- swift 浮点型字符串的运算
- ddos攻击python_Python基于http的ddos攻击代码
- STM32F103的USART1和USART2的TX和RX所对应的分别是那个引脚?
- Ado.Net实现简易(省、市、县)三级联动查询,还附加Access数据
- 各IO 模型对比与总结
- 天池 在线编程 高效作业处理服务(01背包DP)
- memoryTraining记忆训练小游戏
- Python帮你把B站上喜欢的视频下载下来
- Leetcode题目:Reverse String
- Vivaldi for Mac(极速浏览器)支持m1
- [译] TensorFlow 教程 #09 - 视频数据
- 蓝桥杯C语言---基础练习
- Adobe软件中PS、PR、AE、AI软件如何安装【附软件下载】
- android组件搭配
- JAVA毕设项目社区电商平台系统(java+VUE+Mybatis+Maven+Mysql)
- Linux-菜鸟入门自学 (二)
- 根因定位FluxRank论文背景说明
- js判断两个字符串相等问题
- springboot 秒杀系统(二)redis
- LocalStorage存储对象
热门文章
- 特斯拉纯视觉FSD版本Bug频发!马斯克:不认真测试的车主就取消资格
- 只用嘴唇动一动,AI就能合成语音,效果自然流畅看不出破绽
- 4行代码再现《黑客帝国》数字雨,在终端实现的那种
- Momenta完全无人驾驶首次曝光!城区道路混行无接管,遭遇逆行也不怕,特斯拉Waymo路线二合一...
- 重置SQLSERVER表的自增列,让自增列重新计数
- UAVStack的慢SQL数据库监控功能及其实现
- JavaScript创建元素的三种方法特点及对元素的操作
- handlebars.js 用 br替换掉 内容的换行符
- ios开发学习--cocos2d(cocos2d)效果源码分享--系列教程
- [转] SAAS, PAAS, IAAS