Using _bstr_t to pass a parameter of type BSTR * to a function

What is the correct way to do this:

_bstr_t description; errorInfo->GetDescription( &description.GetBSTR() ); 

or

 _bstr_t description; errorInfo->GetDescription( description.GetAddress() ); 

Where IError:GetDescription is defined as:

 HRESULT GetDescription (BSTR *pbstrDescription); 

I know that I could easily do this:

 BSTR description= SysAllocString (L"Whateva")); errorInfo->GetDescription (&description); SysFreeString (description); 

thanks

+6
c ++ bstr
source share
3 answers

BSTR is being counted, I seriously doubt it will work correctly if you use GetAddress (). Unfortunately, the source code is not available for double verification. I always did it like this:

 BSTR temp = 0; HRESULT hr = p->GetDescription(&temp); if (SUCCEEDED(hr)) { _bstr_t wrap(temp, FALSE); // etc.. } 
+8
source share

To answer @Hans answer - the appropriate way to build _bstr_t depends on whether GetDescription returns the BSTR that you have or the one that refers to memory that you don't need to free.

The goal is to minimize the number of copies, but also to avoid manually calling SysFreeString in the returned data. I would modify the code as shown to clarify this:

 BSTR temp = 0; HRESULT hr = p->GetDescription(&temp); if (SUCCEEDED(hr)) { _bstr_t wrap(temp, false); // do not copy returned BSTR, which // will be freed when wrap goes out of scope. // Use true if you want a copy. // etc.. } 
+5
source share

A late response that may not apply to earlier (or later) versions of Visual Studio; However, VS 12.0 has a built-in implementation of _bstr_t , and obviously, an internal instance of Data_t is created with m_RefCount of 1 when GetBSTR() called in virgin _bstr_t . So the _bstr_t life cycle in your first example looks fine:

 _bstr_t description; errorInfo->GetDescription( &description.GetBSTR() ); 

But if _bstr_t dirty, the existing m_wstr internal pointer will be overwritten, which will leak the previous memory to which it refers.

Using the following operator& , dirty _bstr_t can be used if it is first cleared using Assign(nullptr) . Overloading also provides the convenience of using an address operator instead of GetBSTR() ;

 BSTR *operator&(_bstr_t &b) { b.Assign(nullptr); return &b.GetBSTR(); } 

So your first example might look like this:

 _bstr_t description(L"naughty"); errorInfo->GetDescription(&description); 

This rating was based on comutil.h from VS 12.0.

+2
source share

All Articles