何时可以重新分配`[in,out]`参数?

时间:2013-06-06 10:49:13

标签: c++ com bstr

如果我有[in,out] BSTR*参数并且我想修改字符串内容但仍然保持相同的长度,我可以重复使用它还是需要重新分配/释放和分配BSTR

MSDN says

  

对于[in, out]参数,调用者分配内存,方法或   属性可以可选解除分配并重新分配它,以及调用者   最后负责删除内存。

更完整,什么时候可选?

1 个答案:

答案 0 :(得分:1)

  

何时可选

它表示调用者负责提供有效参数(并在必要时分配内存)。

该方法(被调用者)负责将参数保留为有效值。也就是说,它可以自行选择保留现有值,或者,可选,将值更改为另一个值 - 当方法需要以任何理由更改参数时。更改可分配值意味着应取消(释放)旧分配并以相同方式进行新分配,以便接收此值的调用者在不再需要该值时可以安全地释放。

输入/输出字符串参数如下所示。在第一次执行时,它会递增输入值的第一个字符而不重新分配,然后它将用新值替换该值:

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"