文档章节

从Java到C++——从union到VARIANT与CComVariant的深层剖析

自由的角马
 自由的角马
发布于 2015/01/10 13:57
字数 1471
阅读 9
收藏 0

      我第一次用VARIANTCComVariant的时候完全不明白它是怎么回事,为它什么数据类型都可以存放,什么数据都可以被可以初始化?里面到底是怎么实现的?感觉又神奇又迷惑!我们在上一节中讲了union的用法之后你也许想到了大概是怎么回事了。没错,union可以帮我们实现这一个神奇的功能。而且VARIANT定义中确实使用了union。如果你还不明白,那我们就自己来模拟实现一个类似于CComVariant功能的类把,废话不多说,看代码:

CVariate.h:

#ifndef CVARIATE_H
#define CVARIATE_H

#include <string.h>

//======================================================
const unsigned int DEFAULT_STRLEN = 256;
//=======================================================

//自己定义一个类用于存放任意类型的数据,以模拟类型VARIANT的功能。
class CVariate
{
public:
    CVariate() : type(INT), nVal(0){}               //默认构造函数,初始化nVal,值为0
    virtual ~CVariate(){};                          //虚构函数,不做任何处理
    CVariate(const CVariate& val) : type(val.type)  //拷贝构造函数
    {
        CopyUnion(val);
    }
    CVariate &operator=(char c)
    {
        type = CHAR;
        cVal = c;
        return *this;
    }
    CVariate &operator=(short int sn)
    {
        type = SHORT;
        snVal = sn;
        return *this;
    }
    CVariate &operator=(int i)
    {
        type = INT;
        nVal = i;
        return *this;
    }
    CVariate &operator=(long l)
    {
        type = LONG;
        lVal = l;
        return *this;
    }
    CVariate &operator=(float f)
    {
        type = FLOAT;
        fVal = f;
        return *this;
    }
    CVariate &operator=(double d)
    {
        type = DOUBLE;
        dVal = d;
        return *this;
    }
    CVariate &operator=(const char* str);
    void CopyUnion(const CVariate& val);                    //数据的拷贝
    void DisplayValue();
private:
    enum {CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, STR}type;  //为不同的数据类型定义一个枚举值
    union                                                   //union,可以存入各种类型的数据
    {
        char cVal;
        short snVal;
        int nVal;
        long lVal;
        float fVal;
        double dVal;
        char strVal[DEFAULT_STRLEN];
    };
};

#endif // CVARIATE_H
CVariate.cpp:
#include "../include/CVariate.h"
#include <iostream>

CVariate& CVariate::operator=(const char* str)
{
    if(strlen(str) >= DEFAULT_STRLEN)
    {
        std::cerr << "The length of string is out of memory." << std::endl;
    } else
    {
        strcpy(strVal, str);
        type = STR;
    }
    return *this;
}

void CVariate::CopyUnion(const CVariate& val)
{
    switch(val.type)
    {
        case CVariate::CHAR:
            cVal = val.cVal;
            break;
        case CVariate::SHORT:
            snVal = val.snVal;
            break;
        case CVariate::INT:
            nVal = val.nVal;
            break;
        case CVariate::LONG:
            lVal = val.lVal;
            break;
        case CVariate::FLOAT:
            fVal = val.fVal;
            break;
        case CVariate::DOUBLE:
            dVal = val.dVal;
            break;
        case CVariate::STR:
            if(strlen(val.strVal) >= DEFAULT_STRLEN)
            {
                std::cerr << "The length of string is out of memory." << std::endl;
                break;
            } else
            {
                strcpy(strVal, val.strVal);
            }
            break;
        default:
            return;
    }
}


void CVariate::DisplayValue()
{
    switch(type)
    {
        case CVariate::CHAR:
            std::cout << cVal;
            break;
        case CVariate::SHORT:
            std::cout << snVal;
            break;
        case CVariate::INT:
            std::cout << nVal;
            break;
        case CVariate::LONG:
            std::cout << lVal;
            break;
        case CVariate::FLOAT:
            std::cout << fVal;
            break;
        case CVariate::DOUBLE:
            std::cout << dVal;
            break;
        case CVariate::STR:
            char s[255];
            strcpy(s, strVal);
            std::cout << s;
            break;
        default:
            return;
    }
    std::cout << std::endl;
}
Test.cpp:

int main()
{
    CVariate cVal;
    cVal.DisplayValue();
    cVal = 125;
    cVal.DisplayValue();
    CVariate cVal2(cVal);
    cVal2.DisplayValue();
    cVal2 = 188.598;
    cVal2.DisplayValue();
    cVal2 = "Hello World.";
    cVal2.DisplayValue();    
    return 0;
}
结果如下:


VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义如下:

struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
ULONGLONG ullVal; ---VT_UI8
LONGLONG llVal; ---VT_I8
LONG lVal; ---VT_I4 */
BYTE bVal; ---VT_UI1 */
SHORT iVal; ---VT_I2 */
FLOAT fltVal; ---VT_R4 */
DOUBLE dblVal; ---VT_R8 */
VARIANT_BOOL boolVal;   ---VT_BOOL */
_VARIANT_BOOL bool; ---(obsolete) */
SCODE scode; ---VT_ERROR */
CY cyVal; ---VT_CY */
DATE date; ---VT_DATE */
BSTR bstrVal; ---VT_BSTR */
IUnknown * punkVal; ---VT_UNKNOWN */
IDispatch * pdispVal; ---VT_DISPATCH */
SAFEARRAY * parray; ---VT_ARRAY */
BYTE * pbVal; ---VT_BYREF|VT_UI1 */
SHORT * piVal; ---VT_BYREF|VT_I2 */
LONG * plVal; ---VT_BYREF|VT_I4 */
LONGLONG * pllVal; ---VT_BYREF|VT_I8 */
FLOAT * pfltVal; ---VT_BYREF|VT_R4 */
DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */
VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */
_VARIANT_BOOL *pbool; ---(obsolete) */
SCODE * pscode; ---VT_BYREF|VT_ERROR */
CY * pcyVal; ---VT_BYREF|VT_CY */
DATE * pdate; ---VT_BYREF|VT_DATE */
BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */
IUnknown ** ppunkValVARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。

struct tagVARIANT {

union {

struct __tagVARIANT {

VARTYPE vt;

WORD wReserved1;

WORD wReserved2;

WORD wReserved3;

union {

ULONGLONG ullVal; ---VT_UI8

LONGLONG llVal; ---VT_I8

LONG lVal; ---VT_I4 */

BYTE bVal; ---VT_UI1 */

SHORT iVal; ---VT_I2 */

FLOAT fltVal; ---VT_R4 */

DOUBLE dblVal; ---VT_R8 */

VARIANT_BOOL boolVal;   ---VT_BOOL */

_VARIANT_BOOL bool; ---(obsolete) */

SCODE scode; ---VT_ERROR */

CY cyVal; ---VT_CY */

DATE date; ---VT_DATE */

BSTR bstrVal; ---VT_BSTR */

IUnknown * punkVal; ---VT_UNKNOWN */

IDispatch * pdispVal; ---VT_DISPATCH */

SAFEARRAY * parray; ---VT_ARRAY */

BYTE * pbVal; ---VT_BYREF|VT_UI1 */

SHORT * piVal; ---VT_BYREF|VT_I2 */

LONG * plVal; ---VT_BYREF|VT_I4 */

LONGLONG * pllVal; ---VT_BYREF|VT_I8 */

FLOAT * pfltVal; ---VT_BYREF|VT_R4 */

DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */

VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */

_VARIANT_BOOL *pbool; ---(obsolete) */

SCODE * pscode; ---VT_BYREF|VT_ERROR */

CY * pcyVal; ---VT_BYREF|VT_CY */

DATE * pdate; ---VT_BYREF|VT_DATE */

BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */

IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */

IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */

SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */

VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */

PVOID byref; ---Generic ByRef */

CHAR cVal; ---VT_I1 */

USHORT uiVal; ---VT_UI2 */

ULONG ulVal; ---VT_UI4 */

INT intVal; ---VT_INT */
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。

struct tagVARIANT {

union {

struct __tagVARIANT {

VARTYPE vt;

WORD wReserved1;

WORD wReserved2;

WORD wReserved3;

union {

ULONGLONG ullVal; ---VT_UI8

LONGLONG llVal; ---VT_I8

LONG lVal; ---VT_I4 */

BYTE bVal; ---VT_UI1 */

SHORT iVal; ---VT_I2 */

FLOAT fltVal; ---VT_R4 */

DOUBLE dblVal; ---VT_R8 */

VARIANT_BOOL boolVal;   ---VT_BOOL */

_VARIANT_BOOL bool; ---(obsolete) */

SCODE scode; ---VT_ERROR */

CY cyVal; ---VT_CY */

DATE date; ---VT_DATE */

BSTR bstrVal; ---VT_BSTR */

IUnknown * punkVal; ---VT_UNKNOWN */

IDispatch * pdispVal; ---VT_DISPATCH */

SAFEARRAY * parray; ---VT_ARRAY */

BYTE * pbVal; ---VT_BYREF|VT_UI1 */

SHORT * piVal; ---VT_BYREF|VT_I2 */

LONG * plVal; ---VT_BYREF|VT_I4 */

LONGLONG * pllVal; ---VT_BYREF|VT_I8 */

FLOAT * pfltVal; ---VT_BYREF|VT_R4 */

DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */

VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */

_VARIANT_BOOL *pbool; ---(obsolete) */

SCODE * pscode; ---VT_BYREF|VT_ERROR */

CY * pcyVal; ---VT_BYREF|VT_CY */

DATE * pdate; ---VT_BYREF|VT_DATE */

BSTR * pbstrVal; ---VT_VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。

struct tagVARIANT {

union {

struct __tagVARIANT {

VARTYPE vt;

WORD wReserved1;

WORD wReserved2;

WORD wReserved3;

union {

ULONGLONG ullVal; ---VT_UI8

LONGLONG llVal; ---VT_I8

LONG lVal; ---VT_I4 */

BYTE bVal; ---VT_UI1 */

SHORT iVal; ---VT_I2 */

FLOAT fltVal; ---VT_R4 */

DOUBLE dblVal; ---VT_R8 */

VARIANT_BOOL boolVal;   ---VT_BOOL */

_VARIANT_BOOL bool; ---(obsolete) */

SCODE scode; ---VT_ERROR */

CY cyVal; ---VT_CY */

DATE date; ---VT_DATE */

BSTR bstrVal; ---VT_BSTR */

IUnknown * punkVal; ---VT_UNKNOWN */

IDispatch * pdispVal; ---VT_DISPATCH */

SAFEARRAY * parray; ---VT_ARRAY */

BYTE * pbVal; ---VT_BYREF|VT_UI1 */

SHORT * piVal; ---VT_BYREF|VT_I2 */

LONG * plVal; ---VT_BYREF|VT_I4 */

LONGLONG * pllVal; ---VT_BYREF|VT_I8 */

FLOAT * pfltVal; ---VT_BYREF|VT_R4 */

DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */

VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */

_VARIANT_BOOL *pbool; ---(obsolete) */

SCODE * pscode; ---VT_BYREF|VT_ERROR */

CY * pcyVal; ---VT_BYREF|VT_CY */

DATE * pdate; ---VT_BYREF|VT_DATE */

BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */

IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */

IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */

SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */

VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */

PVOID byref; ---Generic ByRef */

CHAR cVal; ---VT_I1 */

USHORT uiVal; ---VT_UI2 */

ULONG ulVal; ---VT_UI4 */

INT intVal; ---VT_INT */

UINT uintVal; ---VT_UINT */

DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */

CHAR * pcVal; ---VT_BYREF|VT_I1 */

USHORT * puiVal; ---VT_BYREF|VT_UI2 */

ULONG * pulVal; ---VT_BYREF|VT_UI4 */

ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */

INT * pintVal; ---VT_BYREF|VT_INT */

UINT * puintVal; ---VT_BYREF|VT_UINT

struct __tagBRECORD {

PVOID pvRecord;

IRecordInfo * pRecInfo;

} __VARIANT_NAME_4; --- VT_RECORD

} __VARIANT_NAME_3;

} __VARIANT_NAME_2;

DECIMAL decVal;

} __VARIANT_NAME_1;

};BYREF|VT_BSTR */

IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */

IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */

SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */

VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */

PVOID byref; ---Generic ByRef */

CHAR cVal; ---VT_I1 */

USHORT uiVal; ---VT_UI2 */

ULONG ulVal; ---VT_UI4 */

INT intVal; ---VT_INT */

UINT uintVal; ---VT_UINT */

DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */

CHAR * pcVal; ---VT_BYREF|VT_I1 */

USHORT * puiVal; ---VT_BYREF|VT_UI2 */

ULONG * pulVal; ---VT_BYREF|VT_UI4 */

ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */

INT * pintVal; ---VT_BYREF|VT_INT */

UINT * puintVal; ---VT_BYREF|VT_UINT

struct __tagBRECORD {

PVOID pvRecord;

IRecordInfo * pRecInfo;

} __VARIANT_NAME_4; --- VT_RECORD

} __VARIANT_NAME_3;

} __VARIANT_NAME_2;

DECIMAL decVal;

} __VARIANT_NAME_1;

};
UINT uintVal; ---VT_UINT */

DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */

CHAR * pcVal; ---VT_BYREF|VT_I1 */

USHORT * puiVal; ---VT_BYREF|VT_UI2 */

ULONG * pulVal; ---VT_BYREF|VT_UI4 */

ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */

INT * pintVal; ---VT_BYREF|VT_INT */

UINT * puintVal; ---VT_BYREF|VT_UINT

struct __tagBRECORD {

PVOID pvRecord;

IRecordInfo * pRecInfo;

} __VARIANT_NAME_4; --- VT_RECORD

} __VARIANT_NAME_3;

} __VARIANT_NAME_2;

DECIMAL decVal;

} __VARIANT_NAME_1;

};; ---VT_BYREF|VT_UNKNOWN */
IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */
SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */
VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */
PVOID byref; ---Generic ByRef */
CHAR cVal; ---VT_I1 */
USHORT uiVal; ---VT_UI2 */
ULONG ulVal; ---VT_UI4 */
INT intVal; ---VT_INT */
UINT uintVal; ---VT_UINT */
DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */
CHAR * pcVal; ---VT_BYREF|VT_I1 */
USHORT * puiVal; ---VT_BYREF|VT_UI2 */
ULONG * pulVal; ---VT_BYREF|VT_UI4 */
ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */
INT * pintVal; ---VT_BYREF|VT_INT */
UINT * puintVal; ---VT_BYREF|VT_UINT
struct __tagBRECORD {
PVOID pvRecord;
IRecordInfo * pRecInfo;
} __VARIANT_NAME_4; --- VT_RECORD
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};


相关说明 参考文章:

http://blog.csdn.net/nppg2008/article/details/7885139

http://blog.csdn.net/china_chentao/article/details/4059698




本文转载自:http://blog.csdn.net/luoweifu/article/details/35797455

自由的角马
粉丝 1
博文 269
码字总数 0
作品 0
文山
私信 提问
android开发教程(3)— jni编程之采用SWIG从Java调用C/C++

Android 从Java调用C/C++ 当无法用 Java 语言编写整个应用程序时,JNI 允许您调用C/C++本机代码。在下列典型情况下,您可能决定使用本机代码: 希望用更低级、更快的编程语言C/C++去实现对时...

刘小米_思聪
2014/09/16
4.7K
0
从Java到JVM到OS线程睡眠

前言 Java 中有时需要将线程进入睡眠状态,这时一般我们就会通过使线程进入睡眠状态,接下去就看看执行该语句在 JVM 中做了什么。 简单例子 以下是一个简单的例子,使主线程睡眠5秒钟。 JVM ...

超人汪小建
2018/08/20
0
0
Android JNI(一)——NDK与JNI基础

本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Native相互调用 Android JNI学习(四)——JNI的常用方法...

隔壁老李头
2018/05/09
0
0
C++不垃圾,只是Java很傲慢

《Thinking in C++》及《Thinking in Java》的作者Bruce Eckel向来是个“拥C++反Java”派,他曾经不止一次的提到,C++语言特性的添加有多么的深思熟虑,而Java又是如何的把一些奇怪的东西不停...

AlphaJay
2010/04/15
762
0
C++不垃圾,只是Java很傲慢

本文转自:http://developer.51cto.com/art/200906/131773.htm 《Thinking in C++》及《Thinking in Java》的作者Bruce Eckel向来是个“拥C++反Java”派,他曾经不止一次的提到,C++语言特性...

张明
2010/03/18
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

kibana汉化

kibana5 / 6 需要下载补丁包,https://github.com/anbai-inc/Kibana_Hanization 其中 v6 版本原生支持国际化,只需要添加资源文件并且配置即可 kibana7 v7版本官方内置汉化资源,在配置文件 ...

细肉云吞
24分钟前
5
0
spring boot 自定义日志 log4j2

使用默认的日志在实际开发中会存在很多问题,比如备份文件名称无法自动重命名、各个等级的日志被放在一个文件中等,所以实际开发中为了更好满足我们的需求,我们一般都会自定义采用配置的方式...

雷开你的门
28分钟前
7
0
PCB设计-Allegro软件入门系列-设计参数配置(上)

前言 经历了导入网表,和放置器件后,我们就要画板子了,但是必要的设计参数也要先准备好,磨刀不误砍柴工。 《一》显示参数 这里主要设置DRC报错标志大小和飞线显示类型 (1)DRC标志可以适当...

demyar
29分钟前
7
0
js实现微博、微信分享

html <!-- 分享 --><div class="share-box"> <b style="vertical-align: middle;">分享到:</b> <a title="分享到新浪微博" class="shareSina"><span class="share-icon"></span><......

张兴华ZHero
45分钟前
7
0
创龙TMS320DM8168浮点DSP C674x + ARM Cortex-A8的CPU、NAND FLASH、NOR FLASH

TL6678-EasyEVM是广州创龙基于SOM-TL6678核心板而研发的一款多核高性能DSP开发板。开发板采用核心板+底板方式,底板采用沉金无铅工艺的四层板设计,尺寸为200mm*106.65mm,它为用户提供了SOM...

Tronlong创龙
48分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部