Когда необязательно перераспределять параметр `[in, out]`?

Если у меня есть [in,out] BSTR* параметр, и я хочу изменить содержимое строки, но при этом сохранить ту же длину, могу ли я просто использовать его повторно или мне нужно перераспределить / освободить и выделить BSTR?

MSDN говорит:

За [in, out] параметры, вызывающая сторона выделяет память, метод или
собственность может по выбору освободить и перераспределить его, и вызывающий
наконец-то отвечает за удаление памяти.

Чтобы быть более полным, когда это необязательно?

1

Решение

когда это необязательно

В нем говорится, что вызывающая сторона отвечает за предоставление действительного аргумента (и выделение памяти, если необходимо).

Метод (вызываемый) также должен оставить параметр с допустимым значением. То есть, по своему усмотрению, он может оставить существующее значение на месте, или, по выбору, измените значение на другое — когда метод должен по какой-либо причине изменить параметр. Изменение выделяемого значения означает, что старое выделение должно быть отменено (освобождено), а новое выделение выполняется таким же образом, чтобы вызывающий абонент, получивший это значение, мог безопасно освободить, когда ему больше не нужно это значение.

Строковый параметр in / out будет выглядеть следующим образом. При первом выполнении он увеличивает первый символ входного значения без перераспределения, затем заменяет значение новым:

STDMETHOD(Method)(/* [in, out] */ BSTR* psValue) throw()
{
if(!psValue)
return E_POINTER;
static INT g_nCounter = 0;
if(++g_nCounter > 1)
{
// Deallocate old, Allocate new
SysFreeString(*psValue);
*psValue = SysAllocString(L"New Value");
} else
{
// No Re-allocation
if(SysStringLen(*psValue) > 0)
(*psValue)[0]++;
}
return S_OK;
}

Код на основе ATL может выглядеть немного лучше:

STDMETHOD(Method)(BSTR* psValue) throw()
{
_ATLTRY
{
ATLENSURE_THROW(psValue, E_POINTER);
CComBSTR& sValue = reinterpret_cast<CComBSTR&>(*psValue);
static INT g_nCounter = 0;
if(++g_nCounter > 1)
{
sValue = _T("New Value");
} else
{
if(sValue.Length() > 1)
sValue[0]++;
}
}
_ATLCATCH(Exception)
{
return Exception;
}
return S_OK;
}

Код стороны вызывающей стороны может быть таким:

CComBSTR sValue = _T("Old Value");
Method(&sValue);
CComBSTR sValueA = sValue; // Gets you "Pld Value"Method(&sValue);
CComBSTR sValueB = sValue; // Gets you "New Value"
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]