_variant_t、CComVariant与COleVariant、CDBVariant

article/2025/10/29 15:43:22


目前计算机语言多种多样,如C++、Java、Basic、Pascal等,此外还有JavaScript、VBScript、ActionScript等脚本语言,它们各自维护自己的数据类型,当使用C++这样强类型的语言来读取数据库或者与其他语言之间来交换数据时,它很有可能不知道获取到的数据的具体类型,这个时候必须借助于变体类型读取数据。VARIANT数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。其在Visual C++中的定义:
typedef tagVARIANT VARIANT;  
typedef struct tagVARIANT VARIANTARG; 
VARIANT 其实是一个结构,结构中用一个vt成员表示数据的类型,同时真正的数据则存储在union空间中。一般我们使用VARIANT的步骤如下所示。
定义一个VARIANT变量,如:var。
通过vt成员设定VARIANT变量的数据类型,如:var.vt = VT_I4。
通过对应的union成员设定数据内容,如:var.lVal = 100。
综上所述,利用VARIANT表示一个整型数据:
VARIANT var;  
var.vt = VT_I4;     //指明整型数据  
var.lVal = 100;     //赋值  
利用VARIANT表示一个布尔值:  
VARIANT var;  
var.vt = VT_BOOL;                   //指明整型数据  
var.boolVal = VARIANT_TRUE;     //赋值  
利用VARIANT保存一个字符串:  
VARIANT var;  
var.vt = VT_BSTR;   
var.bstrVal = SysAllocString(L"hello, world!"); 
根据以上的代码,读者可能会猜到,VARIANT的定义可能类似于如下:
struct VARIANT  
{  
    VARTYPE vt;                     //数据类型  
    union 
    {  
        LONG            lVal;       //VT_I4  
        VARIANT_BOOL    boolVal     //VT_BOOL  
        BSTR            bstrVal;    //VT_BSTR  
    }  
}; 
实际上,VARIANT的定义就是这样的!只不过由于它需要支持的类型太多,所以它包含的联合成员会更多。限于篇幅,在此不再附出。


VARIANT支持的类型,也就是vt成员的取值如表4-3所示。


表4-3 VARIANT支持的类型


类型名


含义


VT_EMPTY


指示未指定值


VT_NULL


指示空值(类似于 SQL 中的空值)


VT_I2


指示 short 整数


VT_I4


指示 long 整数


VT_R4


指示 float 值


VT_R8


指示 double 值


VT_CY


指示货币值


VT_DATE


指示 DATE 值


VT_BSTR


指示 BSTR 字符串


VT_DISPATCH


指示 IDispatch 指针


VT_ERROR


指示 SCODE


VT_BOOL


指示一个布尔值


VT_VARIANT


指示 VARIANTfar 指针


VT_UNKNOWN


指示 IUnknown 指针


VT_DECIMAL


指示 decimal 值


VT_I1


指示 char 值




(续表)






类型名


含义


VT_UI1


指示 byte


VT_UI2


指示 unsignedshort


VT_UI4


指示 unsignedlong


VT_I8


指示 64 位整数


VT_UI8


指示 64 位无符号整数


VT_INT


指示整数值


VT_UINT


指示 unsigned 整数值


VT_VOID


指示 C 样式 void


VT_HRESULT


指示 HRESULT


VT_PTR


指示指针类型


VT_SAFEARRAY


指示 SAFEARRAY


VT_CARRAY


指示 C 样式数组


VT_USERDEFINED


指示用户定义的类型


VT_LPSTR


指示一个以 NULL 结尾的字符串


VT_LPWSTR


指示由 nullNothingnullptrnull


引用(在 Visual Basic


中为 Nothing) 终止的宽字符串


VT_RECORD


指示用户定义的类型


VT_FILETIME


指示 FILETIME 值


VT_BLOB


指示以长度为前缀的字节


VT_STREAM


指示随后是流的名称


VT_STORAGE


指示随后是存储的名称


VT_STREAMED_OBJECT


指示流包含对象


VT_STORED_OBJECT


指示存储包含对象


VT_BLOB_OBJECT


指示 Blob 包含对象


VT_CF


指示剪贴板格式


VT_CLSID


指示类 ID


VT_VECTOR


指示简单的已计数数组


VT_ARRAY


指示 SAFEARRAY 指针


VT_BYREF


指示 值为引用


 

4.2.5  _variant_t、CComVariant与COleVariant、CDBVariant

从上面可以看出VARIANT这种类型使用起来比较复杂,其实有简单的办法,那就是采用VARIANT的封装类_variant_t。_variant_t的构造函数接受基本数据类型的数据作为参数,如下列出其中的一小部分:

   
  1. _variant_t(  
  2.    short sSrc,  
  3.    VARTYPE vtSrc = VT_I2   
  4. );  
  5.  
  6. _variant_t(  
  7.    long lSrc,  
  8.    VARTYPE vtSrc = VT_I4   
  9. );  
  10.  
  11. _variant_t(  
  12.    float fltSrc   
  13. throw( );  
  14.  
  15. _variant_t(  
  16.    double dblSrc,  
  17.    VARTYPE vtSrc = VT_R8   
  18. ); 

另一方面,_variant_t提供了反向的转换函数,如将一个_variant_t转换成一个short数值,如下列出其中的一小部分:

   
  1. operator short( ) const;   
  2. operator long( ) const;   
  3. operator float( ) const;   
  4. operator double( ) const

因此可以看出,利用_variant_t可以很方便地实现VARIANT类型和基本数据类型之间的转换,如:

   
  1. long l = 123;  
  2. _variant_t lVal(l);  
  3. long m = lVal; 

也可以用COleVariant和CComVariant来简化对VARIANT的操作,代码参考如下:

   
  1. COleVariant v3 = _T("hello, world!");  
  2. COleVariant v4 = (long)1999;  
  3. CString str = (BSTR)v3.pbstrVal;  
  4. long i = v4.lVal; 

VARIANT类图如图4-7所示。

 
(点击查看大图)图4-7  VARIANT类图
此外,在MFC ODBC 编程中,我们还会接触到CDBVariant,CDBVariant没有任何基类,它的功能与COleVariant相似,唯一的差别是它不使用OLE。可以看出,Visual C++为变体提供了太多的封装类,如果可行的话,我们建议读者尽量在自己的代码中采用统一的类,如:_variant_t。

http://chatgpt.dhexx.cn/article/gUcTyUOo.shtml

相关文章

Partial correlation coefficient

利用PYTHON计算偏相关系数(Partial correlation coefficient) 在统计学中,我们经常使用皮尔逊相关系数来衡量两个变量之间的线性关系。然而,有时我们感兴趣的是理解两个变量之间的关系,同时控制第三个变量。 例如,假设…

Multilevel Cooperative Coevolution for Large Scale Optimization

0、论文背景 本文在CCEA_G的基础上,提出了MLCC框架。在MLCC中,基于不同组大小的随机分组策略构造了一组问题分解器。演化过程分为若干个循环,在每个周期开始时,MLCC使用自适应机制根据其历史性能选择分解器。由于不同的组大小捕获…

mean value coordinates(均值重心坐标)定义及证明

欢迎关注更多精彩 关注我,学习常用算法与数据结构,一题多解,降维打击。 在图形学中对于物体的描述往往是离散,但是在具体展示过程中我们又希望是连续。线性插值是解决离散与连续的常用手段。 三角形中的插值点击前往凸四边形中的…

numpy中的convolve的理解

写在前面 浏览更多内容,可访问:http://www.growai.cn 欢迎您关注作者知乎:ML与DL成长之路 推荐关注公众号:AI成长社,ML与DL的成长圣地。 函数 numpy.convolve(a, v, mode‘full’),这是numpy函数中的卷…

Clustering Coefficient

Define Clustering Coefficient:聚类系数 Clustering Coefficient measures the degree to which nodes in a network tend to cluster or form triangles. ——聚类系数衡量网络中节点倾向于聚类或形成三角形的程度 Triadic Closure 三元闭包 The tendency of…

covariate(covariate是控制变量吗)

如何用STATA对连续性变量进行meta回归分析 在stata中有个metareg命令,好像可以对连续变量进行回归分析。 附件中是一篇pdf文档,主要介绍stata中关于meta分析的命令。跟大家分享一下。 里面在提到metareg命令时,列举了以下三个列子&#xff1a…

协方差矩阵简介(Covariance Matrix)

协方差矩阵定义 首先我们要明白,协方差实际是在概率论和统计学中用于衡量两个变量的总体误差,当然方差是协方差的一种特殊情况,即当两个变量是相同情况。它表示的是两个变量的总体的误差,这与只表示一个变量误差的方差不同。如果两个变量的变…

covariance matrix

协方差的定义 对于一般的分布,直接代入E(X)之类的就可以计算出来了,但真给你一个具体数值的分布,要计算协方差矩阵,根据这个公式来计算,还真不容易反应过来。这里用一个例子说明协方差矩阵是怎么计算出来的吧。 记住&…

经典排序算法——堆排序

对于一个int数组,请编写一个堆排序算法,对数组元素排序。 给定一个int数组A及数组的大小n,请返回排序后的数组。 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] class HeapSort { public:int* heapSort(int* A, int n) {BuildMaxHeap(…

堆排序算法原理及c++实现

文章目录 准备知识MAX-HEAPIFY过程建堆堆排序算法总结 准备知识 堆的结构可以分为最大堆和最小堆,是一个完全二叉树,而堆排序是根据堆的这种数据结构设计的一种排序。 所谓完全二叉树即叶节点只能出现在最下层和次下层,并且最下面一层的结点…

堆排序算法设计与分析

堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。堆分为大根堆和小根堆,是完全二叉树。大根堆要求父结点的值大于或等于子结点的值,小根堆相反。根据大根堆的性质,我们可以知道最大值一…

堆排序算法实现

堆排序:结构逻辑上是完全二叉树,但是可以使用顺序存储来实现 一些二叉树的区别: 二叉树:度数最大为2并且每个子树也是二叉树 满二叉树:每层节点都是满的,没有空缺,也就是,叶子节点只能出现在最后一层 完全二叉树:限制条件比满二叉树弱化,只需要前k-1层是满二叉树结构,最后…

数据结构之堆排序算法详解+C语言实现

堆   堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。 堆排序   堆排序是利用堆这种数据结构而设计的一种排序算法&…

堆排序算法原理及实现

堆排序是排序中一种比较重要的算法,和快速排序一样,其复杂度也是O(nlogn);同时也是一种原地排序算法:在任何时候,数组中只有常数个元素存储在输入数组以外。堆这种数据结构是处理海量数据比较常见的结构,海…

堆排序算法Java

基本原理 1):将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素 2):将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆; 3):重复步骤2 小知识…

堆排序算法详细分析

一、堆相关概念 1.堆 堆是完全二叉树,即除最后一层外,其它层都是满的,且最后一层从左到右依次都有元素。如下图所示。 堆是用数组来实现的,图中下标就为数组的下标,其对应数组[5, 1, 7, 2, 8, 6, 3, 9, 4]&#xf…

数据结构——堆排序(算法)

基本介绍 1)、堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最好、最坏、平均时间复杂度均为O(nlogn),它也是不稳定排序。2)、堆是具有以下性质的完全二叉树:每个节点的值都…

C++:堆排序算法详解

图解排序算法(三)之堆排序 预备知识 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆 堆是具有…

排序算法:堆排序算法实现及分析

堆排序介绍 堆排序(Heap Sort)就来利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆…

堆排序算法 总结

最近面试,老是被问到堆排序算法。 回答时老是感觉思路不清楚,现在总结一下,把思路弄清楚的。 1.堆排序是利用堆的特性对记录序列进行排序的一种排序方法。 好的那么堆得特性是什么呢? 堆得定义: 堆是满足下列性质的数…