Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use BSTR*

Tags:

com

bstr

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?

like image 576
Sana Avatar asked May 27 '11 05:05

Sana


People also ask

What is BSTR in c++?

A BSTR (Basic string or binary string) is a string data type that is used by COM, Automation, and Interop functions. Use the BSTR data type in all interfaces that will be accessed from script. C++ Copy.

How to define BSTR?

A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator. The following table describes these components. A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string.

How do I allocate with Bstr?

Allocate BSTR BSTR can be allocated using SysAllocString() API using header file oleauto. h. It takes an WIDE string or unicode string and returns the BSTR buffer. A failure case is handled by returning NULL to the caller.

How do you convert Bstr to Cstring?

Strings of type BSTR must be allocated by the function SysAllocString() that expects an OLECHAR string, hence in Win32/64 a wide string. If you want to copy a _bstr_t that contains Unicode to a CStringA you must convert it to UTF8. I use the classes CW2A and CA2W for conversion.


1 Answers

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;
  }
like image 159
sharptooth Avatar answered Sep 22 '22 00:09

sharptooth