How to use BSTR*
Asked Answered
R

4

6

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?

Relly answered 27/5, 2011 at 5:10 Comment(0)
A
9

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;
  }
Argumentative answered 27/5, 2011 at 8:28 Comment(0)
A
4

Apart from what Martyn has answered, you should try using CComBSTR for this which will automatically take care of allocation and freeing the BSTRs.

BTW, CComBSTR class is an example of RAII

Asgard answered 27/5, 2011 at 5:46 Comment(0)
T
2

If you call SysAllocString twice, you will leak the first BSTR. You should not do this. You can instead SysFreeString on the first BSTR and then SysAllocString on a second, or more simply call SysReAllocString to reallocate your existing BSTR value.

Martyn

Tanberg answered 27/5, 2011 at 5:25 Comment(0)
A
0

If you function defined as:

HRESULT Foo(BSTR input){...}

Call it like:

Foo(_bstr_t(L"abc"));
Asthenia answered 24/7, 2013 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.