views:

225

answers:

2

I'm new to COM. What exactly is the advantage of replacing:

L"String"

with

CComBSTR(L"String")

I can see a changelist in the COM part of my .NET application where all strings are replaced in this way. Would like to know what is the need for this.

A: 

You could just pass L"Something" into a COM method declared as expecting a BSTR but you should never do so.

The convention is that a BSTR is allocated using one of SysAllocString() family functions and anyone who receives a BSTR can (and should) call SysStringLen() whenever they want to find the string length. SysStringLen() relies on the BSTR being allocated with SysAllocString() family functions (since it uses extra data allocated and initialized by those functions) and if that requirement is violated the program will run into undefined behaviour.

Using SysAllocString() directly requires also calling SysFreeString() to free the string (otherwise memory is leaked) so it leads to lots of code and possibly to errors. The better way is just using a wrapper class such as CComBSTR or _bstr_t for managing the BSTRs - they will call SysAllocString()/SysFreeString() when necessary (unless you abuse them, of course).

sharptooth
+1  A: 

BSTR is not the same as WCHAR[]. BSTR values are prefixed with their length, as well as null-terminated.

If you're dealing with in-process objects that are written in C or C++, you'll usually get away with this, because the C/C++ code will probably assume that your BSTR is a null-terminated wide character string.

If, on the other hand, you're dealing with out-of-process/cross-machine objects, the proxy/stub marshalling code will assume that you really did pass a BSTR, and will expect to find a length field (it needs this to know how much data to marshal). This will go horribly wrong.

In short: if something expects a BSTR, call SysAllocString (or CComBSTR, or CString::AllocSysString).

Roger Lipscombe

related questions