Как использовать BSTR*

#com #bstr

#com #bstr

Вопрос:

У меня есть 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? Каков наилучший способ справиться с этим?

Ответ №1:

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

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

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

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

Ответ №2:

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

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

Ответ №3:

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

Мартин

Ответ №4:

Если ваша функция определена как:

 HRESULT Foo(BSTR input){...}
  

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

 Foo(_bstr_t(L"abc"));