views:

66

answers:

4
+1  Q: 

ComBSTR assignment

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

+1  A: 

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.)

Chris Jester-Young
+2  A: 

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.

Nestor
+1  A: 

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.

tyranid
+3  A: 

A real BSTR is:

  • temporarily allocated from the COM heap (via SysAllocString() and family)
  • a data structure in which the string data is preceded by its length, stored in a 32-bit value.
  • passed as a pointer to the fifth byte of that data structure, where the string data resides.

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.

Heath Hunnicutt

related questions