How to use BSTR*

Sana picture Sana · May 27, 2011 · Viewed 11.6k times · Source

I have an out value as BSTR* for an interface in a C++ COM dll. And I am returning this to a C# .Net client. In my C++ function I have to assign different values according to a diff condition.

For example:

If my function is fun(BSTR* outval)
{
   // I have to assign a default value to it such as:
   *outval = SysAllocSTring(L"N");

   Then I will check for some DB conditions
   { 
     // And I have to allocate it according to that.
     // Do I need to again calling SysAllocString?
     eq.*outval = SySAllocString(DBVlaue);
   }
}

What happens if I call SysAllocSTring two times to the same BSTR? What is the best way to handle this?

Answer

sharptooth picture sharptooth · May 27, 2011

You have to take care of all BSTRs except the one you actually pass as the "out" parameter. The BSTR you pass out need not be freed - the caller becomes responsible for freeing it, and your code is responsible for all other BSTRs it could have allocated.

If you really need those temporary BSTRs you should use a wrapper class like ATL::CComBSTR or _bstr_t for those temporary BSTRs (but not for the one you pass out). I guess in the case you describe you'll be much better off just rewriting your code in such way that you don't need more that one BSTR creation on any control path.

Here's some pseudocode:

 HRESULT YourFunction( BSTR* result )
 {
     if( result == 0 ) {
         return E_POINTER;
     }
     int internalStateValue = getState();
     if( internalStateValue > 0 ) { // first case
         *result = SysAllocString( "positive" );
     } else if( internalStateValue < 0 ) { //second case
         *result = SysAllocString( "negative" );
     } else { //default case
         *result = SysAllocString( "zero" );
     }
     return S_OK;
  }