Работа с COM/ATL типами
От: Аноним  
Дата: 16.11.09 14:52
Оценка:
Здравствуйте.
На входе в функцию получаю массив GUID'ов и его размер, далее его надо передать в функцию в виде указателя на VARIANT, содержащего массив SAFEARRAY элементов типа BSTR, значения элементов — те же самые GUID'ы. Делаю вот так:

HRESULT SomeFunc(VARIANT*);

HRESULT OtherFunc(const GUID* pElems, std::size_t nElem)
{
    std::vector<CComBSTR> bsvecElems(nElem);
    CComSafeArray<BSTR> saElems;
    
    for(std::size_t i = 0 ; i < nElem ; ++i)
    {
        CComBSTR bsItem = pElems[i];
        
        bsvecElems.push_back(bsItem);
        saElems.Add(bsItem);
    }

    CComVariant svElems(saElems);
    
    return SomeFunc(&svElems);
}

При помощи вектора CComBSTR-строк я пытаюсь гарантировать время их жизни, чтобы в функцию SomeFunc передавались валидные строки.

Вопрос такой. Можно сделать все проще?
Re: Работа с COM/ATL типами
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.11.09 06:22
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>На входе в функцию получаю массив GUID'ов и его размер, далее его надо передать в функцию в виде указателя на VARIANT, содержащего массив SAFEARRAY элементов типа BSTR, значения элементов — те же самые GUID'ы. Делаю вот так:


А>Вопрос такой. Можно сделать все проще?

HRESULT OtherFunc(const GUID* pElems, std::size_t nElem)
{
    CComSafeArray<BSTR> saElems(nElem);
    
    for(std::size_t i = 0 ; i < nElem ; ++i)
    {
//        saElems[i] = pElems[i];
        saElems[i].Attach(CComBSTR(pElems[i]).Detach());
    }

    VARIANT vElems; // без деструктора
    V_VT(&vElems) = VT_ARRAY | VT_BSTR;
    V_ARRAY(&vElems) = saElems;
    return SomeFunc(&vElems);

//    CComVariant svElems; // без копирования, но ссылка на массив SAFEARRAY элементов типа BSTR
//    V_VT(&svElems) = VT_BYREF | VT_ARRAY | VT_BSTR;
//    V_ARRAYREF(&svElems) = saElems.GetSafeArrayPtr();
//    return SomeFunc(&svElems);
}
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Работа с COM/ATL типами
От: Аноним  
Дата: 17.11.09 15:10
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Аноним, Вы писали:


А>>На входе в функцию получаю массив GUID'ов и его размер, далее его надо передать в функцию в виде указателя на VARIANT, содержащего массив SAFEARRAY элементов типа BSTR, значения элементов — те же самые GUID'ы. Делаю вот так:


А>>Вопрос такой. Можно сделать все проще?

Vi2>
Vi2>HRESULT OtherFunc(const GUID* pElems, std::size_t nElem)
Vi2>{
Vi2>    CComSafeArray<BSTR> saElems(nElem);
    
Vi2>    for(std::size_t i = 0 ; i < nElem ; ++i)
Vi2>    {
Vi2>//        saElems[i] = pElems[i];
Vi2>        saElems[i].Attach(CComBSTR(pElems[i]).Detach());
Vi2>    }

Vi2>    VARIANT vElems; // без деструктора
Vi2>    V_VT(&vElems) = VT_ARRAY | VT_BSTR;
Vi2>    V_ARRAY(&vElems) = saElems;
Vi2>    return SomeFunc(&vElems);

Vi2>//    CComVariant svElems; // без копирования, но ссылка на массив SAFEARRAY элементов типа BSTR
Vi2>//    V_VT(&svElems) = VT_BYREF | VT_ARRAY | VT_BSTR;
Vi2>//    V_ARRAYREF(&svElems) = saElems.GetSafeArrayPtr();
Vi2>//    return SomeFunc(&svElems);
Vi2>}
Vi2>


Спасибо за ответ!
А когда будет происходить освобождение BSTR-строк? В функции SomeFunc освобождение не делается. Хотя могу добавить — она тоже моя.
Или может лучше вернуться к CComVariant'у, чтобы массив строк освобождался по выходу из функции?

А что значит закомментированная строка:
// saElems[i] = pElems[i];

Это альтернативный вариант записи saElems[i].Attach(CComBSTR(pElems[i]).Detach()); ?
Re[3]: Работа с COM/ATL типами
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.11.09 22:20
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>А когда будет происходить освобождение BSTR-строк? В функции SomeFunc освобождение не делается. Хотя могу добавить — она тоже моя.

А>Или может лучше вернуться к CComVariant'у, чтобы массив строк освобождался по выходу из функции?

CComSafeArray<BSTR> saElems, как SAFEARRAY строк, освободит эти строки во время своего деструктора. Если задействовать CComVariant, то придется копировать массив строк туда, потому что тоже есть деструктор. Закомментированный вариант с CComVariant svElems не будет освобождать массив в деструкторе, но требует спец.обработки в функции SomeFunc.

А>А что значит закомментированная строка:

А>// saElems[i] = pElems[i];

А>Это альтернативный вариант записи saElems[i].Attach(CComBSTR(pElems[i]).Detach()); ?

Да, сначала была первая строка, но такого оператора нет в описании класса. Пришлось сделать через конструктор.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.