#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"));