_variant_t与其他数据类型的转换
转自:http://kuaixingdong.blog.hexun.com/29627840_d.html
我们先看看COM所支持的一些类型的基本类:
(微软提供,在comdef.h中定义)
在COM中使用的标准类Class如下所示:
_bstr_t:对BSTR类型进行打包,并提供有用的操作和方法;
_com_error:定义抛出的error对象;
_com_ptr_t:封装COM接口指针
_variant_t:对VARIANT类型进行打包,并提供有用的操作和方法;
一、_variant_t类的简单介绍:
_variant_t对象封装了VARIANT数据类型。
The class manages resource allocation and deallocation and makes function calls to VariantInit and VariantClear as appropriate.
(1) _variant类提供的方法:
1> 构造函数
_variant_t
对_variant_t变量初始化调用的是_variant_t的构造函数。我们一般习惯于用一个int型的变量对数字类的变量进行初始化,这对_variant_t变量是不允许的。
原因很简单,_variant_t 的构造函数中没有用整型( Int )对其初始化的构造函数
可先将整型转化成long,然后再对其进行初始化
2> Attach()
Attaches a VARIANT object into the _variant_t object.
3> Clear()
Clears the encapsulated VARIANT object.
4> ChangeType
Changes the type of the _variant_t object to the indicated VARTYPE.
5> Detach
Detaches the encapsulated VARIANT object from this _variant_t object.
6> SetString
将一个string赋值给_variant_t对象;
7> Operators
赋值操作,给现有的_variant_t对象赋一个新值;
8> operator ==, !=
对比两个 _variant_t 对象是否相等;
9> Extractors
Extract data from the encapsulated VARIANT object.
(2) _variant_t的定义:
_variant_t类封闭了VARIANT数据类型,VARIANT是一个结构体类型,我们可以看一下它的定义
- typedef struct tagVARIANT
- {
- VARTYPE vt; //存储数据类型
- unsigned short wReserved1;
- unsigned short wReserved2;
- unsigned short wReserved3;
- union
- {
- Byte bVal; // VT_UI1.
- Short iVal; // VT_I2.
- long lVal; // VT_I4.
- float fltVal; // VT_R4.
- double dblVal; // VT_R8.
- VARIANT_BOOL boolVal; // VT_BOOL.
- SCODE scode; // VT_ERROR.
- CY cyVal; // VT_CY.
- DATE date; // VT_DATE.
- BSTR bstrVal; // VT_BSTR.
- DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
- IUnknown FAR* punkVal; // VT_UNKNOWN.
- IDispatch FAR* pdispVal; // VT_DISPATCH.
- SAFEARRAY FAR* parray; // VT_ARRAY|*.
- Byte FAR* pbVal; // VT_BYREF|VT_UI1.
- short FAR* piVal; // VT_BYREF|VT_I2.
- long FAR* plVal; // VT_BYREF|VT_I4.
- float FAR* pfltVal; // VT_BYREF|VT_R4.
- double FAR* pdblVal; // VT_BYREF|VT_R8.
- VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL.
- SCODE FAR* pscode; // VT_BYREF|VT_ERROR.
- CY FAR* pcyVal; // VT_BYREF|VT_CY.
- DATE FAR* pdate; // VT_BYREF|VT_DATE.
- BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR.
- IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN.
- IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH.
- SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*.
- VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT.
- void FAR* byref; // Generic ByRef.
- char cVal; // VT_I1.
- unsigned short uiVal; // VT_UI2.
- unsigned long ulVal; // VT_UI4.
- int intVal; // VT_INT.
- unsigned int uintVal; // VT_UINT.
- char FAR * pcVal; // VT_BYREF|VT_I1.
- unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
- unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
- int FAR * pintVal; // VT_BYREF|VT_INT.
- unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.
- };
- };
注意:vt用来存储内部变量(联合体中保存的变量)的类型,联合体用来存储对应类型的值
二、数据类型转换
_bstr_t类可以作为_variant_t类与基本数据类型转换的中介
(1) _variant_t与CString之间的转化
1> CString转换为_variant_t:
- CString str;
- _variant_t str1=(LPCTSTR)str;
使用_variant_t的成员函数SetString来对_variant_t的对象赋值会更好;
2> _variant_t转换为CString:
- _variant_t vt;
- CString tempstr=(LPCSTR)_bstr_t(vt); //_bstr_t的构造函数有对_variant_t类型的处理
(2) _variant_t与char *之间的转换
1> char * 转换为_variant_t
方法与CString转换为_variant_t的方法类似:
- char * cValue;
- _variant_t vValue=(LPSTR)cValue;
2> _variant_t转换为char *:
错误方法:
- _variant_t vValue;
- char * value=(LPSTR)(LPCSTR)_bstr_t(vValue)
value指向一堆乱码...
原因:不能用char *直接指向(LPSTR)(LPCSTR)_bstr_t( _variant_t ),因为这样转换之后实际上是一个string,而非一个char *
正确方法:
进行转换时,只能用strcpy(),将LPSTR指向的字符复制到char * 所指向的内存中;
如下例:
- _variant_t vValue;
- char cValue[16]={0};
- strcpy(cValue, (LPCSTR)_bstr_t(vValue));
(3) 判断_variant_t的值类型
下面的转换代码根据_variant_t的vt进行类型判断,然后将数据值转换为CString类型(可作为转换为其他数据类型的中介)
- CString str;
- //以下代码演示如何转换为C标准字符串型
- switch(var.vt)
- {
- case VT_BSTR:
- {
- str=var.bstrVal;
- break;
- }
- case VT_I2: //var is short int type
- {
- str.Format("%d",(int)var.iVal);
- break;
- }
- case VT_I4: //var is long int type
- {
- str.Format("%d", var.lVal);
- break;
- }
- case VT_R4: //var is float type
- {
- str.Format("%10.6f", (double)var.fltVal);
- break;
- }
- case VT_R8: //var is double type
- {
- str.Format("%10.6f", var.dblVal);
- break;
- }
- case VT_CY: //var is CY type
- {
- str=COleCurrency(var).Format();
- break;
- }
- case VT_DATE: //var is DATE type
- {
- str=COleDateTime(var).Format();
- break;
- }
- case VT_BOOL: //var is VARIANT_BOOL
- {
- str= (var.boolVal==0) ?"FALSE": "TRUE";
- break;
- }
- default:
- {
- str.Format("Unk type %d\n",var.vt);
- TRACE("Unknown type %d\n",var.vt);
- break;
- }
- }
_variant_t与其他数据类型的转换的更多相关文章
- _variant_t 与其他数据类型的转换
在COM中使用的标准类Class如下所示: _bstr_t:对BSTR类型进行打包,并提供有用的操作方法: _com_error:定义抛出的error对象; _com_ptr_t:封装COM接口指针 ...
- java中数据类型的转换
数据类型的转换,分为自动转换和强制转换. 自动转换是程序执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换 强制转换必须在代码中声明,转换顺序不受限制 自动数据类 ...
- Java的基本数据类型与转换
1.1 Java为什么需要保留基本数据类型 http://www.importnew.com/11915.html 基本数据类型对大多数业务相关或网络应用程序没有太大的用处,这些应用一般是采用客户端/ ...
- java的数据类型的转换
一:java的数据类型转换除布尔类型boolean(不能转换)有两种:<一> 自动转换: <二> 强制转换 <一>.自动转换:就是将小的数据类型自动转换成大的数据类 ...
- JavaScript学习笔记——数据类型强制转换和隐式转换
javascript数据类型强制转换 一.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 B.如果是数字,转换成为本身.将无意义的后导 ...
- JAVA数据类型自动转换,与强制转换
一.数据类型自动转换 public class Test{ public static void main(String[] args){ int a = 1; double b = 1.5; dou ...
- Java学习笔记之:Java数据类型的转换
一.介绍 数据类型的转换,分为自动转换和强制转换.自动转换是程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换:强制类型转换则必须在代码中声明,转换顺序不受 ...
- 语言基础:C#输入输出与数据类型及其转换
今天学习了C#的定义及特点,Visual Studio.Net的集成开发环境和C#语言基础. C#语言基础资料——输入输出与数据类型及其转换 函数的四要素:名称,输入,输出,加工 输出 Console ...
- C#基础(八)——C#数据类型的转换
C#数据类型的转换主要有以下几种方式: 1.强制转换 注意:char类型不能强制转换成int,如果使用强制转化,得到的是原整数的ASCII码值. 2.class.parse(string类型的变量), ...
随机推荐
- unity 返回子对象组件
Component[] GetComponentsInChildren(Type t, bool includeInactive = false); //includeInactive: 是否查找非激 ...
- com.google.gson的SerializedName解决实体类与关键字的重名
使用google的gson包,解决实体类中字段与java关键字的重名: // 比如 当实体类中有switch关键字时,解决冲突如下 @SerializedName("switch" ...
- Containerpilot 配置文件 之 Jobs
ContainerPilot job是用户定义的进程和规则,用于何时执行它,如何进行健康检查,以及如何向Consul做广告. 这些规则旨在允许灵活性覆盖几乎可能要运行的任何类型的进程. 一些可能的jo ...
- 新手C#SQL Server使用记录2018.08.10
主键(PrimaryKey):主键就是每个数据行(记录)的唯一标识,不会有重复值的列(字段)才能当做主键.一个表可以没有主键,但是这样会很难处理表,因此一般情况表都要设置主键. 主键有两张选用策略,分 ...
- selenium -- 鼠标悬停
针对页面上的二级菜单,需要鼠标悬停才能进行操作. /** * Clicks (without releasing) in the middle of the given element. This i ...
- tag-SMASS-1
SMASS 是在vasp的DFTMD中决定着系综的类型,在手册中给出的该参数具体信息如下: SMASS = -3 | -2 | -1 | [real] ≥ 0 Default: SMASS = -3 ...
- Django搭建数据库
---恢复内容开始--- 一.form表单提交数据的三个要素 1.form标签必须要有action个和method属性 2.所有获取用户输入的标签必须放在form表单中,必须要有name属性 3.必须 ...
- chest
chest - 必应词典 美[tʃest]英[tʃest] n.胸部:胸膛:有…胸的:胸部…的 网络胸围:箱子:胸腔 变形复数:chests:
- Linux xxd命令
一.简介 xxd 命令用于使用二进制或十六进制格式显示文件内容,可以将指定文件或标准输入以十六进制转储,也可以把十六进制转储转换成原来的二进制形式. 二.选项 http://www.cnblogs.c ...
- PAT 1084 外观数列(20)(代码+思路+推荐测试用例)
1084 外观数列(20 分) 外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ... 它从不等于 1 的数字 d 开始,序列的第 ...