Здравствуйте.
На входе в функцию получаю массив 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 передавались валидные строки.
Вопрос такой. Можно сделать все проще?
Здравствуйте, Аноним, Вы писали:
А>На входе в функцию получаю массив 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);
}
Здравствуйте, 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()); ?
Здравствуйте, Аноним, Вы писали:
А>А когда будет происходить освобождение BSTR-строк? В функции SomeFunc освобождение не делается. Хотя могу добавить — она тоже моя.
А>Или может лучше вернуться к CComVariant'у, чтобы массив строк освобождался по выходу из функции?
CComSafeArray<BSTR> saElems, как SAFEARRAY строк, освободит эти строки во время своего деструктора. Если задействовать CComVariant, то придется копировать массив строк туда, потому что тоже есть деструктор. Закомментированный вариант с CComVariant svElems не будет освобождать массив в деструкторе, но требует спец.обработки в функции SomeFunc.
А>А что значит закомментированная строка:
А>// saElems[i] = pElems[i];
А>Это альтернативный вариант записи saElems[i].Attach(CComBSTR(pElems[i]).Detach()); ?
Да, сначала была первая строка, но такого оператора нет в описании класса. Пришлось сделать через конструктор.