How to best convert CString to BSTR to pass it as an "in" parameter into a COM method?

sharptooth picture sharptooth · Jan 18, 2010 · Viewed 15.1k times · Source

I need to convert a CString instance into a properly allocated BSTR and pass that BSTR into a COM method. To have code that compiles and works indentically for both ANSI and Unicode I use CString::AllocSysString() to convert whatever format CString to a Unicode BSTR.

Since noone owns the returned BSTR I need to take care of it and release it after the call is done in the most exception-safe manner posible and with as little code as possible.

Currently I use ATL::CComBSTR for lifetime management:

 ATL::CComBSTR converted;
 converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it
 interface->CallMethod( converted );

what I don't like here is that I need two separate statements to just construct the ATL::CComBSTR bound to the convertion result.

Is there a better way to accomplish the same task?

Answer

Phil Booth picture Phil Booth · Jan 18, 2010

CComBSTR has overloaded constructors for both char* and wchar_t*, which make the call to SysAllocString() on your behalf. So the explicit allocation in your code snippet is actually unnecessary. The following would work just as well:

ATL::CComBSTR converted = sourceString;
interface->CallMethod(converted);

Furthermore, if you have no need to use the converted BSTR elsewhere in your code, you can perform the object construction in-place in the method call, like so:

interface->CallMethod(ATL::CComBSTR(sourceString));

The same applies to the _bstr_t class, which can be used instead of CComBSTR if you don't want a dependency on the ATL.