VC中BSTR、bstr_t、CComBSTR的定义

一、BSTR数据类型

1、BSTR的定义

参考C:\Program Files\Microsoft SDKs\v6.0A \Include\wtypes.h中BSTR的定义:

typedef OLECHAR __RPC_FAR *BSTR;

typedef WCHAR OLECHAR;

typedef wchar_t WCHAR;

再参考C:\Program Files\Microsoft SDKs\v5.0\Include\Basetyps.h 中wchar_t的定义:

typedef unsigned short wchar_t;

 

二、bstr_t类

1、_bstr_t类的定义

参考C:\Program Files\Microsoft Visual Studio 9.0 \VC\Include\comutil.h

class _bstr_t {

public:

    // Constructors   

    _bstr_t() throw();

    _bstr_t(const _bstr_t& s) throw();

    _bstr_t(const char* s) ;

    _bstr_t(const wchar_t* s) ;

    _bstr_t(const _variant_t& var) ;

    _bstr_t(BSTR bstr, bool fCopy) ;

 

    // Destructor   

    ~_bstr_t() throw();

 

    // Assignment operators   

    _bstr_t& operator=(const _bstr_t& s) throw();

    _bstr_t& operator=(const char* s) ;

    _bstr_t& operator=(const wchar_t* s) ;

    _bstr_t& operator=(const _variant_t& var) ;

 

    // Operators   

    _bstr_t& operator+=(const _bstr_t& s) ;

    _bstr_t operator+(const _bstr_t& s) const ;

 

    // Friend operators   

    friend _bstr_t operator+(const char* s1, const _bstr_t& s2) ;

    friend _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2) ;

 

    // Extractors   

    operator const wchar_t*() const throw();

    operator wchar_t*() const throw();

    operator const char*() const ;

    operator char*() const ;

 

    // Comparison operators   

    bool operator!() const throw();

    bool operator==(const _bstr_t& str) const throw();

    bool operator!=(const _bstr_t& str) const throw();

    bool operator<(const _bstr_t& str) const throw();

    bool operator>(const _bstr_t& str) const throw();

    bool operator<=(const _bstr_t& str) const throw();

    bool operator>=(const _bstr_t& str) const throw();

 

    // Low-level helper functions    

    BSTR copy(bool fCopy = true) const ;

    unsigned int length() const throw();

 

    // Binary string assign   

    void Assign(BSTR s) ;

 

    // Get the physical BSTR   

    BSTR& GetBSTR() ;

    BSTR* GetAddress() ;

 

    // Attach to the internal BSTR w/o copying   

    void Attach(BSTR s) ;

 

    // Detach the internal BSTR   

    BSTR Detach() throw();

 

private:

    // Referenced counted wrapper   

    class Data_t {

    public:

        // Constructors       

        Data_t(const char* s) ;

        Data_t(const wchar_t* s) ;

        Data_t(BSTR bstr, bool fCopy) ;

        Data_t(const _bstr_t& s1, const _bstr_t& s2) ;

 

        // Reference counting routines       

        unsigned long AddRef() throw();

        unsigned long Release() throw();

        unsigned long RefCount() const throw();

 

        // Extractors       

        operator const wchar_t*() const throw();

        operator const char*() const ;

 

        // Low-level helper functions       

        const wchar_t* GetWString() const throw();

        wchar_t*& GetWString() throw();

        const char* GetString() const ;

 

        BSTR Copy() const ;

        void Assign(BSTR s) ;

        void Attach(BSTR s) throw();

        unsigned int Length() const throw();

        int Compare(const Data_t& str) const throw();

 

        // Exception agnostic wrapper for new       

        void* operator new(size_t sz);         

 

    private:

        BSTR            m_wstr;

        mutable char*   m_str;

        unsigned long   m_RefCount;

 

        // Never allow default construction       

        Data_t() throw();

 

        // Never allow copy       

        Data_t(const Data_t& s) throw();

 

        // Prevent deletes from outside. Release() must be used.

        ~Data_t() throw();

 

        void _Free() throw();

    };

 

private:

    // Reference counted representation   

    Data_t* m_Data;

 

private:

    // Low-level utilities

    void _AddRef() throw();

    void _Free() throw();

    int _Compare(const _bstr_t& str) const throw();

};

 

三、CComBSTR类

1、CComBSTR的定义

参考C:\Program Files\Microsoft Visual Studio 9.0 \VC \atlmfc\Include\atlcomcli.h

class CComBSTR

{

public:

BSTR m_str;

    CComBSTR()

    {

        m_str = NULL;

    }

    CComBSTR(int nSize)

    {

        m_str = ::SysAllocStringLen(NULL, nSize);

    }

    CComBSTR(int nSize, LPCOLESTR sz)

    {

        m_str = ::SysAllocStringLen(sz, nSize);

    }

    CComBSTR(LPCOLESTR pSrc)

    {

        m_str = ::SysAllocString(pSrc);

    }

    CComBSTR(const CComBSTR& src)

 {

        m_str = src.Copy();

 }

    CComBSTR(REFGUID src)

    {

       LPOLESTR szGuid;

       StringFromCLSID(src, &szGuid);

       m_str = ::SysAllocString(szGuid);

       CoTaskMemFree(szGuid);

    }

    CComBSTR& operator=(const CComBSTR& src)

    {

       if (m_str != src.m_str)

       {

          if (m_str)

             ::SysFreeString(m_str);

          m_str = src.Copy();

       }

       return *this;

    }

 

 CComBSTR& operator=(LPCOLESTR pSrc)

    {

       ::SysFreeString(m_str);

       m_str = ::SysAllocString(pSrc);

       return *this;

    }

 

  ~CComBSTR()

    {

       ::SysFreeString(m_str);

  }

  unsigned int Length() const

    {

       return (m_str == NULL)? 0 : SysStringLen(m_str);

    }

    operator BSTR() const

    {

       return m_str;

  }

    BSTR* operator&()

    {

       return &m_str;

    }

    BSTR Copy() const

    {

       return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));

    }

    HRESULT CopyTo(BSTR* pbstr)

  {

       ATLASSERT(pbstr != NULL);

       if (pbstr == NULL)

         return E_POINTER;

       *pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));

       if (*pbstr == NULL)

          return E_OUTOFMEMORY;

       return S_OK;

    }

  void Attach(BSTR src)

    {

       ATLASSERT(m_str == NULL);

       m_str = src;

    }

    BSTR Detach()

    {

       BSTR s = m_str;

       m_str = NULL;

       return s;

    }

    void Empty()

    {

       ::SysFreeString(m_str);

       m_str = NULL;

    }

    bool operator!() const

    {

       return (m_str == NULL);

    }

    HRESULT Append(const CComBSTR& bstrSrc)

    {

       return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));

    }

    HRESULT Append(LPCOLESTR lpsz)

    {

       return Append(lpsz, ocslen(lpsz));

    }

  // a BSTR is just a LPCOLESTR so we need a special version to signify

  // that we are appending a BSTR

    HRESULT AppendBSTR(BSTR p)

    {

       return Append(p, SysStringLen(p));

    }

  HRESULT Append(LPCOLESTR lpsz, int nLen)

  {

       int n1 = Length();

       BSTR b;

       b = ::SysAllocStringLen(NULL, n1+nLen);

       if (b == NULL)

          return E_OUTOFMEMORY;

       memcpy(b, m_str, n1*sizeof(OLECHAR));

       memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));

       b[n1+nLen] = NULL;

       SysFreeString(m_str);

       m_str = b;

       return S_OK;

    }

  HRESULT ToLower()

    {

       USES_CONVERSION;

       if (m_str != NULL)

       {

          LPTSTR psz = CharLower(OLE2T(m_str));

          if (psz == NULL)

             return E_OUTOFMEMORY;

         BSTR b = T2BSTR(psz);

         if (psz == NULL)

             return E_OUTOFMEMORY;

         SysFreeString(m_str);

         m_str = b;

     }

     return S_OK;

    }

    HRESULT ToUpper()

    {

      USES_CONVERSION;

      if (m_str != NULL)

      {

          LPTSTR psz = CharUpper(OLE2T(m_str));

          if (psz == NULL)

             return E_OUTOFMEMORY;

          BSTR b = T2BSTR(psz);

          if (psz == NULL)

              return E_OUTOFMEMORY;

          SysFreeString(m_str);

          m_str = b;

      }

      return S_OK;

   }

 bool LoadString(HINSTANCE hInst, UINT nID)

   {

      USES_CONVERSION;

      TCHAR sz[512];

      UINT nLen = ::LoadString(hInst, nID, sz, 512);

      ATLASSERT(nLen < 511);

      SysFreeString(m_str);

      m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;

      return (nLen != 0);

   }

 bool LoadString(UINT nID)

   {

      return LoadString(_pModule->m_hInstResource, nID);

   }

 

   CComBSTR& operator+=(const CComBSTR& bstrSrc)

   {

      AppendBSTR(bstrSrc.m_str);

      return *this;

   }

   bool operator<(BSTR bstrSrc) const

   {

        if (bstrSrc == NULL && m_str == NULL)

            return false;

        if (bstrSrc != NULL && m_str != NULL)

            return wcscmp(m_str, bstrSrc) < 0;

        return m_str == NULL;

   }

 bool operator==(BSTR bstrSrc) const

 {

        if (bstrSrc == NULL && m_str == NULL)

           return true;

        if (bstrSrc != NULL && m_str != NULL)

           return wcscmp(m_str, bstrSrc) == 0;

        return false;

   }

 bool operator<(LPCSTR pszSrc) const

   {

       if (pszSrc == NULL && m_str == NULL)

           return false;

       USES_CONVERSION;

       if (pszSrc != NULL && m_str != NULL)

           return wcscmp(m_str, A2W(pszSrc)) < 0;

       return m_str == NULL;

 }

 bool operator==(LPCSTR pszSrc) const

   {

       if (pszSrc == NULL && m_str == NULL)

          return true;

       USES_CONVERSION;

       if (pszSrc != NULL && m_str != NULL)

          return wcscmp(m_str, A2W(pszSrc)) == 0;

       return false;

   }

#ifndef OLE2ANSI

   CComBSTR(LPCSTR pSrc)

   {

      m_str = A2WBSTR(pSrc);

   }

 

   CComBSTR(int nSize, LPCSTR sz)

   {

      m_str = A2WBSTR(sz, nSize);

   }

 

 void Append(LPCSTR lpsz)

   {

      USES_CONVERSION;

      LPCOLESTR lpo = A2COLE(lpsz);

      Append(lpo, ocslen(lpo));

 }

 

 CComBSTR& operator=(LPCSTR pSrc)

   {

      ::SysFreeString(m_str);

      m_str = A2WBSTR(pSrc);

      return *this;

   }

#endif

   HRESULT WriteToStream(IStream* pStream)

 {

      ATLASSERT(pStream != NULL);

      ULONG cb;

     ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0;

      HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);

      if (FAILED(hr))

        return hr;

      return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;

   }

   HRESULT ReadFromStream(IStream* pStream)

   {

       ATLASSERT(pStream != NULL);

       ATLASSERT(m_str == NULL); // should be empty

       ULONG cbStrLen = 0;

       HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);

      if ((hr == S_OK) && (cbStrLen != 0))

      {

         //subtract size for terminating NULL which we wrote out

         //since SysAllocStringByteLen overallocates for the NULL

         m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));

         if (m_str == NULL)

            hr = E_OUTOFMEMORY;

         else

            hr = pStream->Read((void*) m_str, cbStrLen, NULL);

      }

      if (hr == S_FALSE)

         hr = E_FAIL;

      return hr;

   }

};

上一篇:Base64转Blob的方式


下一篇:C语言代码段