VARIANT、 _variant_t、CComVariant、COleVariant、CDBVariant

参考文章

http://blog.163.com/[email protected]/blog/static/16219623020107634935586/

http://blog.csdn.net/dreamcs/article/details/7186633

http://blog.sina.com.cn/s/blog_6c3d32da0100ua13.html

COleVariant是数据库常用到的数据类型。它可以是字串,整型值,日期等。知道怎样将它转换为CString很有用处。

设有CString A; COleVariant B; 来看看怎样将COleVariant转换为CString:

switch(B.vt){

case VT_BSTR:   A=V_BSTRT(&B); break;//COleVariant是一个字串

case VT_I2:   A.Format(_T("%hd"),V_I2(&B));break;//是短整型

case VT_I4:   A.Format(_T("%d"),V_I4(&B));break;//是长整型

case VT_R4:   A.Format(_T("%e"),(double)V_R4(&B));break;//是浮点数

case VT_R8:   A.Format(_T("%e"),V_R8(&B));break;//是浮点数

case VT_CY:   A=COleCurrency(B).Format();break;//是货币值

case VT_DATE: A=COleDateTime(B).Format("%Y-%m-%d");break;//是日期

case VT_BOOL: A=V_BOOL(&B)?"True":"False";break;//是布尔值

}

//----------------------------------------------------------------------------------------------------------
我发现 A=V_BSTRT(&B);   只能传递一个字符,有问题。
用下面这个方法,两句话就直接可以解决。哈哈,有时网上的东西还是要思考下
B.ChangeType(VT_BSTR);
A=B.bstrVal;

目前计算机语言多种多样,如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


指示值为引用

.2.5  _variant_t、CComVariant与COleVariant、CDBVariant

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

_variant_t(     short sSrc,     VARTYPE vtSrc = VT_I2   );   _variant_t(     long lSrc,     VARTYPE vtSrc = VT_I4   );   _variant_t(     float fltSrc   ) throw( );   _variant_t(     double dblSrc,     VARTYPE vtSrc = VT_R8   ); 

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

operator short( ) const;   operator long( ) const;   operator float( ) const;   operator double( ) const; 

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

long l = 123;  _variant_t lVal(l);  long m = lVal; 

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

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

VARIANT类图如图4-7所示。

498)this.style.width=498;" height=190> 
(点击查看大图)图4-7  VARIANT类图

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

时间: 2025-01-22 00:13:19

VARIANT、 _variant_t、CComVariant、COleVariant、CDBVariant的相关文章

下载-深入浅出Netty源码剖析、Netty实战高性能分布式RPC、NIO+Netty5各种RPC架构实战演练三部曲视频教程

下载-深入浅出Netty源码剖析.Netty实战高性能分布式RPC.NIO+Netty5各种RPC架构实战演练三部曲视频教程 第一部分:入浅出Netty源码剖析 第二部分:Netty实战高性能分布式RPC 第三部分:NIO+Netty5各种RPC架构实战演练

bos 第4 (区域excel批量导入、区域通用分页查询、分区的添加、分区多条件分页查询、分区导出excel)

BOS项目笔记 第4天 今天内容安排: 1.区域批量导入功能 jQuery OCUpload(一键上传插件).apache POI.pinyin4j 2.实现区域的分页查询 3.对分页代码重构 4.添加分区(combobox下拉框) 5.分区的组合条件分页查询 6.分区数据导出功能 1. 区域数据批量导入功能 1.1 一键上传插件使用 ajax不能做文件上传. 第一步:在jsp页面中引入插件的js文件 <script type="text/javascript" src=&quo

Python学习笔记 之 递归、二维数组顺时针旋转90&#176;、正则表达式

递归.二维数组顺时针旋转90°.正则表达式 1.   递归算法是一种直接或间接调用自身算法的过程. 特点: 递归就是在过程或函数里调用自身 明确的递归结束条件,即递归出口 简洁,但是不提倡 递归次数多容易造成栈溢出 要求: 每次调用递归规模上有所减小 前一次为后一次做准备 规模较小时必须直接给出解答而不再进行递归调用 例子:递归实现二分法 1 def searchMyData(mydate,a1): 2 mid = int(len(mydate)/2) 3 if mid >= 1: 4 if m

Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别

http://www.cnblogs.com/xrq730/p/4839245.html 前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出和内存泄露的区别 1.内存溢出 内存溢出指的是程序在申请内存的时候,没有足够大的空间可以分配了. 2.内存泄露 内存泄露指的是程序在申请内存之后,没有办法释放掉已经申请到内存,它始终占用着内存,即被分配的对象可

JavaScript - 简介、在HTMl中使用JavaScript、基本概念

1. JavaScript简介 JavaScript历史回顾 JavaScript是什么 JavaScript与ECMAScript的关系 JavaScript的不同版本 一言概之,略. 2. 在HTML中使用JavaScript 要把JavaScript放到网页中,就得涉及Web的核心语言 -- HTML.当初开发JavaScript的时候,要解决的一个重要问题就是让JavaScript与HTML页面共存,并且不影响页面在浏览器中的呈现效果.最终决定为Web增加统一的脚本支持. 2.1 <sc

Probabilistic Graphical Models:一、Introduction and Overview(1、Overview and Motivation)

一.PGM用来做什么 1.  医学诊断:从各种病症分析病人得了什么病,该用什么手段治疗 2.  图像分割:从一张百万像素级的图片中分析每个像素点对应的是什么东西 两个共同点:(1)有非常多不同的输入变量:(2)对于算法而言,结果都是不确定的 二.PGM各代表什么 1.  Models 2.  Probabilistic (1)概率:设计model即是为了分析一些不确定的东西(uncertainty) (2)Uncertainty的来源: (3)概率在模型表达上的优势 3.  Graphical

block使用小结、在arc中使用block、如何防止循环引用

引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题 : [小测试]你真的知道blocks在Objective-C中是怎么工作的吗?,发现竟然做错了几道, 才知道自己想当然的理解是错误的,所以抽时间学习了下,并且通过一些测试代码进行测试,产生这篇博客. Block简介(copy一段) Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事.需要注意的是由于Objective-C在iOS中不支

Objective-C-类(static)方法、实例方法、overwrite(覆写)、属性(property)复习

先来定义一个Human父类 定义部分: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // //  Human.h //  OOP // //  Created by jimmy.yang on 11-2-9. //  Copyright 2011 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> @interface Human :

VS中生成、清理项目、调试、开始执行(不调试)、Debug 和 Release等之间的区别

一.生成和重新生成 "生成"的时候只对你改动过的文件重新生成没有改动过的文件不会重新生成: "重新生成"是对所有的文件都重新生成. 以cpp为例当你只改动某些.cpp之类的文件的时候可以用生成省了编译没有改动的那些些文件的时间:但是改动了某些.h之类的文件最好用重新生成,因为有可能能有些文件包含.h文件也需要重新编译 选择生成或生成解决方案,将只编译自上次生成以来更改过的那些些项目文件和组件 注意 如果解决方案中包括多个项目,则生成命令将变成生成解决方案. 选择重新