VARIANT的使用

VARIANT是一个联合结构体,完整的定义为:

typedef 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;
} VARIANT, *LPVARIANT, VARIANTARG, *LPVARIANTARG;

为方便操作,定义了另外一个类_variant_t,完整定义为:

class _variant_t : public ::tagVARIANT {
public:
    // Constructors
    //
    _variant_t() throw();

    _variant_t(const VARIANT& varSrc) ;
    _variant_t(const VARIANT* pSrc) ;
    _variant_t(const _variant_t& varSrc) ;

    _variant_t(VARIANT& varSrc, bool fCopy) ;          // Attach VARIANT if !fCopy

    _variant_t(short sSrc, VARTYPE vtSrc = VT_I2) ;    // Creates a VT_I2, or a VT_BOOL
    _variant_t(long lSrc, VARTYPE vtSrc = VT_I4) ;     // Creates a VT_I4, a VT_ERROR, or a VT_BOOL
    _variant_t(float fltSrc) throw();                                   // Creates a VT_R4
    _variant_t(double dblSrc, VARTYPE vtSrc = VT_R8) ; // Creates a VT_R8, or a VT_DATE
    _variant_t(const CY& cySrc) throw();                                // Creates a VT_CY
    _variant_t(const _bstr_t& bstrSrc) ;               // Creates a VT_BSTR
    _variant_t(const wchar_t *pSrc) ;                  // Creates a VT_BSTR
    _variant_t(const char* pSrc) ;                     // Creates a VT_BSTR
    _variant_t(IDispatch* pSrc, bool fAddRef = true) throw();           // Creates a VT_DISPATCH
    _variant_t(bool boolSrc) throw();                                   // Creates a VT_BOOL
    _variant_t(IUnknown* pSrc, bool fAddRef = true) throw();            // Creates a VT_UNKNOWN
    _variant_t(const DECIMAL& decSrc) throw();                          // Creates a VT_DECIMAL
    _variant_t(BYTE bSrc) throw();                                      // Creates a VT_UI1

    _variant_t(char cSrc) throw();                                      // Creates a VT_I1
    _variant_t(unsigned short usSrc) throw();                           // Creates a VT_UI2
    _variant_t(unsigned long ulSrc) throw();                            // Creates a VT_UI4
    _variant_t(int iSrc) throw();                                       // Creates a VT_INT
    _variant_t(unsigned int uiSrc) throw();                             // Creates a VT_UINT
#if (_WIN32_WINNT >= 0x0501)
    _variant_t(__int64 i8Src) throw();                                  // Creates a VT_I8
    _variant_t(unsigned __int64 ui8Src) throw();                        // Creates a VT_UI8
#endif

    // Destructor
    //
    ~_variant_t() throw() ;

    // Extractors
    //
    operator short() const ;                           // Extracts a short from a VT_I2
    operator long() const ;                            // Extracts a long from a VT_I4
    operator float() const ;                           // Extracts a float from a VT_R4
    operator double() const ;                          // Extracts a double from a VT_R8
    operator CY() const ;                              // Extracts a CY from a VT_CY
    operator _bstr_t() const ;                         // Extracts a _bstr_t from a VT_BSTR
    operator IDispatch*() const ;                      // Extracts a IDispatch* from a VT_DISPATCH
    operator bool() const ;                            // Extracts a bool from a VT_BOOL
    operator IUnknown*() const ;                       // Extracts a IUnknown* from a VT_UNKNOWN
    operator DECIMAL() const ;                         // Extracts a DECIMAL from a VT_DECIMAL
    operator BYTE() const ;                            // Extracts a BTYE (unsigned char) from a VT_UI1
    operator VARIANT() const throw();

    operator char() const ;                            // Extracts a char from a VT_I1
    operator unsigned short() const ;                  // Extracts a unsigned short from a VT_UI2
    operator unsigned long() const ;                   // Extracts a unsigned long from a VT_UI4
    operator int() const ;                             // Extracts a int from a VT_INT
    operator unsigned int() const ;                    // Extracts a unsigned int from a VT_UINT
#if (_WIN32_WINNT >= 0x0501)
    operator __int64() const ;                         // Extracts a __int64 from a VT_I8
    operator unsigned __int64() const ;                // Extracts a unsigned __int64 from a VT_UI8
#endif

    // Assignment operations
    //
    _variant_t& operator=(const VARIANT& varSrc) ;
    _variant_t& operator=(const VARIANT* pSrc) ;
    _variant_t& operator=(const _variant_t& varSrc) ;

    _variant_t& operator=(short sSrc) ;                // Assign a VT_I2, or a VT_BOOL
    _variant_t& operator=(long lSrc) ;                 // Assign a VT_I4, a VT_ERROR or a VT_BOOL
    _variant_t& operator=(float fltSrc) ;              // Assign a VT_R4
    _variant_t& operator=(double dblSrc) ;             // Assign a VT_R8, or a VT_DATE
    _variant_t& operator=(const CY& cySrc) ;           // Assign a VT_CY
    _variant_t& operator=(const _bstr_t& bstrSrc) ;    // Assign a VT_BSTR
    _variant_t& operator=(const wchar_t* pSrc) ;       // Assign a VT_BSTR
    _variant_t& operator=(const char* pSrc) ;          // Assign a VT_BSTR
    _variant_t& operator=(IDispatch* pSrc) ;           // Assign a VT_DISPATCH
    _variant_t& operator=(bool boolSrc) ;              // Assign a VT_BOOL
    _variant_t& operator=(IUnknown* pSrc) ;            // Assign a VT_UNKNOWN
    _variant_t& operator=(const DECIMAL& decSrc) ;     // Assign a VT_DECIMAL
    _variant_t& operator=(BYTE bSrc) ;                 // Assign a VT_UI1

    _variant_t& operator=(char cSrc) ;                 // Assign a VT_I1
    _variant_t& operator=(unsigned short usSrc) ;      // Assign a VT_UI2
    _variant_t& operator=(unsigned long ulSrc) ;       // Assign a VT_UI4
    _variant_t& operator=(int iSrc) ;                  // Assign a VT_INT
    _variant_t& operator=(unsigned int uiSrc) ;        // Assign a VT_UINT
#if (_WIN32_WINNT >= 0x0501)
    _variant_t& operator=(__int64 i8Src) ;             // Assign a VT_I8
    _variant_t& operator=(unsigned __int64 ui8Src) ;   // Assign a VT_UI8
#endif

    // Comparison operations
    //
    bool operator==(const VARIANT& varSrc) const throw();
    bool operator==(const VARIANT* pSrc) const throw();

    bool operator!=(const VARIANT& varSrc) const throw();
    bool operator!=(const VARIANT* pSrc) const throw();

    // Low-level operations
    //
    void Clear() ;

    void Attach(VARIANT& varSrc) ;
    VARIANT Detach() throw();

    VARIANT& GetVARIANT() throw();
    VARIANT* GetAddress() ;

    void ChangeType(VARTYPE vartype, const _variant_t* pSrc = NULL) ;

    void SetString(const char* pSrc) ; // used to set ANSI string
};

通常的操作方法为,使用VARIANT定义变量,使用 _variant_t 初始化变量值。

但给类成员变量赋值字符串值时会有问题。

例如:

class A{
public;   
 VARIANT m_var;
}

A a;
a.m_var = _variant_t(“1234”);

这种情况下,m_var中存放的是个野指针,实际的指针在_variant_t的析构函数中被释放了。

如果是其他类型的数据,这种赋值方式是没问题的。

正确的做法应该是这样的:

m_var.vt=VT_STR;
m_var.bstrVal=SysAllocString("1234");

考虑代码的严谨性,整个类应该这样设计:

class A{
public;   
    VARIANT m_var;
    A::A()
    {}
    A::A(LPCTSTR str)
    {
        VariantInit(&m_var);
        m_var.vt = VT_BSTR;
        m_var.bstrVal=SysAllocString(str);
    }
    A::~A()
    {
        if (m_var.vt = VT_BSTR)
        {
            SysFreeString(m_var.bstrVal);
        }
        VariantClear(&m_var);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值