Как пользоваться BSTR * - PullRequest
6 голосов
/ 27 мая 2011

У меня есть значение out как BSTR * для интерфейса в C ++ COM dll.И я возвращаю это клиенту C # .Net.В моей функции C ++ я должен назначать различные значения в соответствии с условием diff.

Например:

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);
   }
}

Что произойдет, если я дважды вызову SysAllocSTring для одного и того же BSTR?Каков наилучший способ справиться с этим?

Ответы [ 4 ]

9 голосов
/ 27 мая 2011

Вы должны позаботиться обо всех BSTR с, кроме того, которое вы фактически передаете в качестве параметра "out".BSTR, которые вы раздаете, не нужно освобождать - вызывающий становится ответственным за его освобождение, а ваш код отвечает за все другие BSTR s, которые он мог бы выделить.

Если вам действительно нужны эти временные BSTR s, вы должны использовать класс-оболочку, например ATL::CComBSTR или _bstr_t, для этих временных BSTR s (но не для того, который вы выдавали).Я предполагаю, что в случае, если вы опишете, вам будет гораздо лучше просто переписать свой код таким образом, что вам не нужно больше, чем одно BSTR создание на любом пути управления.

Вот некоторый псевдокод:1013 *

 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;
  }
3 голосов
/ 27 мая 2011

Помимо ответа Мартина, вы должны попытаться использовать для этого CComBSTR , который автоматически позаботится о выделении и освобождении BSTR.

Кстати, класс CComBSTR является примером RAII

2 голосов
/ 27 мая 2011

Если вы дважды вызовете SysAllocString, вы пропустите первый BSTR. Вы не должны этого делать. Вместо этого вы можете использовать SysFreeString для первого BSTR, а затем SysAllocString для второго или, проще, вызвать SysReAllocString для перераспределения существующего значения BSTR.

Martyn

0 голосов
/ 24 июля 2013

Если вы используете функцию, определенную как:

HRESULT Foo(BSTR input){...}

Назовите это как:

Foo(_bstr_t(L"abc"));
...