on ATL (vi)--BSTR and CComBSTR class

Source: Internet
Author: User

In my writing, I discussed the nature of the Varaint type in detail in ATL (iv)--variant and CComVariant, and explained in detail why CComVariant could be a complete substitute for varaint, I'm going to explain the BSTR and CComBSTR in detail, but unlike Varaint and CComVariant, CComVariant is a subclass of Varaint, and when passing parameters, it is the concept of the subclass object Is-a the parent class. Are the BSTR and ccombstr the same kind of relationship? No! Let's first look at the definition of a BSTR:

typedef OLECHAR __RPC_FAR *bstr;

typedef WCHAR OLECHAR;

typedef wchar_t WCHAR;

typedef unsigned short wchar_t;

Through this series of macro definitions, you can clearly see the nature of the BSTR, it is not a struct, not a class, but a few layers of the built-in data type vest, from which we can also assert that the CComBSTR class is certainly not a child of a BSTR, How can the CComBSTR be the perfect substitute for a BSTR? Let's just take a look at the definition of CComBSTR, and honestly, these codes are really like artwork.

CComBSTR

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 is 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), &AMP;CB);
if (FAILED (HR))
return HR;
Return Cbstrlen? Pstream->write ((void*) m_str, Cbstrlen, &AMP;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;
}
};

I marked the need for attention in red bold, and by the definition of CComBSTR we can see that CComBSTR is a top class, with no complex social backgrounds (such as a lot of inheritance and precompiled directives, etc.), and constructors and assignment operators provide a lot of Basically can satisfy the use of initialization and assignment operations, the most in place of the service is I marked in red bold two functions, one is forced type conversion, through similar operator overloading way to complete, this grammar general beginner is unfamiliar, suggest further study; one is operator overloading on & symbols. These two functions can act as a CComBSTR class and operate a BSTR, which means you can do this, assuming you want to invoke a function that looks like this:

void TEST (BSTR Str1, BSTR *pstr2, BSTR STR3);

Let's say you define a variable like this:

BSTR BSTR;

CComBSTR CoBstr1, COBSTR2;

It is perfectly possible to use COBSTR1 and COBSTR2 as a variant of the BSTR type when calling the test function, as follows:

TEST (BSTR, &COBSTR1, COBSTR2); The call cannot be passed in VC6.0?

What's up, great!


This article is from the "8403723" blog, please be sure to keep this source http://8413723.blog.51cto.com/8403723/1729788

on ATL (vi)--BSTR and CComBSTR class

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.