I'm confused about COM string assignments. Which of the following string assignment is correct. Why?
CComBSTR str;
.
.
Obj->str = L"" //Option1
OR should it be
Obj->str = CComBSTR(L"") //Option2
What is the reason
I'm confused about COM string assignments. Which of the following string assignment is correct. Why?
CComBSTR str;
.
.
Obj->str = L"" //Option1
OR should it be
Obj->str = CComBSTR(L"") //Option2
What is the reason
Personally, I'd prefer option 1, because that doesn't require constructing a new CComBSTR
object. (Whether their code does so behind the scenes is a different story, of course.)
If you use str = CComBSTR(L"")
you use the constructor:
CComBSTR( LPCSTR pSrc );
If you use str = L""
you use the assignment operator:
CComBSTR& operator =(LPCSTR pSrc);
They both would initialize the CComBSTR object correctly.
Option 1 is preferred because it only does one allocation for the string where as option 2 does 2 (not withstanding the creation of a new temporary object for no particular reason). Unlike the bstr_t type in VC++ the ATL one does not do referenced counted strings so it will copy the entire string across.
A real BSTR
is:
SysAllocString()
and family)See the documentation: MSDN: BSTR
Most functions which accept a BSTR
will not crash when passed a BSTR created the simple assignment. This leads to confusion as people observe what seems to be working code from which they infer that a BSTR
can be initialized just like any WCHAR *
. That inference is incorrect.
Only real BSTRs
can be passed to OLE Automation interfaces.
By using the CComBSTR()
constructor, which calls SysAllocString()
, your code will create a real BSTR
. The CComBSTR()
destructor will take care of returning the allocated storage to the system via SysFreeString()
.
If you pass the CComBSTR()
to an API which takes ownership, be sure to call the .Detach()
method to ensure the BSTR
is not freed. BSTRs
are not reference counted (unlike COM objects, which are), and therefore an attempt to free a BSTR
more than once will crash.