Как разобрать Safearray из C++?
От: vic_mx6_2.5_V6_dohc США http://codeforfood.org
Дата: 05.05.02 20:38
Оценка:
как воспроизвести на C++ разборку Визуал Бейсиковскго массива,
возвращаемого com-объектом?

вот кусок моего кода — я подготавливаю пустой массив.
записываю его в вариант и передаю указатель на этот вариант


// Make a safe array
SAFEARRAY *pSA = NULL;
SAFEARRAYBOUND bound[1];
bound[0].lLbound = 0;
bound[0].cElements = nCount;
pSA = SafeArrayCreate(VT_BSTR, 1, bound);
// Pack array into VARIANT
VARIANT var;
VariantInit(&var);
var.vt = VT_ARRAY | VT_BSTR;
var.parray = pSA;

pCart->GetShoppingCart(&var);

VARIANT v_elem;
VariantInit(&v_elem);
v_elem.vt = VT_BSTR;
for(long i=0; i<nCount; i++)
{
SafeArrayGetElement(pSA, &i, &v_elem);
}
Re: Как разобрать Safearray из C++?
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.05.02 21:39
Оценка:
Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:

Посмотри эту статью http://www.rsdn.ru/article/?com/COMvs.xml
Автор(ы): Чистяков В.Ю.

Эта статья входит в цикл "COM vs. CORBA" и знакомит читателя с основами COM, начиная с интерфейса IUnknown
и заканчивая маршалингом, DCOM и COM+.


Сделай поиск по этому сайту на SAFEARRAY.

PS

И в следующий раз форматируй код тегом [ccode], а то читать невозможно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Как разобрать Safearray из C++?
От: Аноним  
Дата: 05.05.02 22:30
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:


VD>Посмотри эту статью http://www.rsdn.ru/article/?com/COMvs.xml
Автор(ы): Чистяков В.Ю.

Эта статья входит в цикл "COM vs. CORBA" и знакомит читателя с основами COM, начиная с интерфейса IUnknown
и заканчивая маршалингом, DCOM и COM+.


VD>Сделай поиск по этому сайту на SAFEARRAY.


VD>PS


VD>И в следующий раз форматируй код тегом [ccode], а то читать невозможно.


сорри я чайник :-) [cccode] будет отступы сохранять?
поиск почему-то не показал ни одной статьи. даже расширенный
Re[3]: Как разобрать Safearray из C++?
От: Андрей Россия  
Дата: 06.05.02 02:24
Оценка:
Здравствуйте Аноним, Вы писали:

А>сорри я чайник [cccode] будет отступы сохранять?


[ccode] будет, только лучше их делать пробелами, а не табуляцией
Re: Как разобрать Safearray из C++?
От: George_Seryakov Россия  
Дата: 06.05.02 03:09
Оценка:
Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:

VM2VD>вот кусок моего кода — я подготавливаю пустой массив.

VM2VD>записываю его в вариант и передаю указатель на этот вариант


VM2VD> pCart->GetShoppingCart(&var);


VM2VD> VARIANT v_elem;

VM2VD> VariantInit(&v_elem);
VM2VD> v_elem.vt = VT_BSTR;
VM2VD> for(long i=0; i<nCount; i++)
VM2VD> {
VM2VD> SafeArrayGetElement(pSA, &i, &v_elem);
VM2VD> }

Тебе вернется новое значение var и var.parray в нем не будет прежним pSA.
GS
Re[3]: Как разобрать Safearray из C++?
От: George_Seryakov Россия  
Дата: 06.05.02 03:10
Оценка:
Здравствуйте Аноним, Вы писали:

А>поиск почему-то не показал ни одной статьи. даже расширенный


Поиск не работает.
GS
Re[2]: Как разобрать Safearray из C++?
От: Аноним  
Дата: 06.05.02 05:25
Оценка:
Здравствуйте George_Seryakov, Вы писали:

GS>Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:


VM2VD>>вот кусок моего кода — я подготавливаю пустой массив.

VM2VD>>записываю его в вариант и передаю указатель на этот вариант


VM2VD>> pCart->GetShoppingCart(&var);


VM2VD>> VARIANT v_elem;

VM2VD>> VariantInit(&v_elem);
VM2VD>> v_elem.vt = VT_BSTR;
VM2VD>> for(long i=0; i<nCount; i++)
VM2VD>> {
VM2VD>> SafeArrayGetElement(pSA, &i, &v_elem);
VM2VD>> }

GS>Тебе вернется новое значение var и var.parray в нем не будет прежним pSA.


мне и не надо чтоб он был прежним (он пустой был)
почему я не могу прочитать ничего через GetElement?
тип возвращаемого VAR-а 8204 что эквивалентно VT_ARRAY | VT_VARIANT
в варианте должны быть строки однако bstrVal содержит пустоту
(0xcccccccc Bad ptr)
или это изначально неправильный способ чтения массива?
Re[2]: Как разобрать Safearray из C++?
От: Аноним  
Дата: 06.05.02 05:36
Оценка:
Здравствуйте George_Seryakov, Вы писали:

GS>Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:


VM2VD>>вот кусок моего кода — я подготавливаю пустой массив.

VM2VD>>записываю его в вариант и передаю указатель на этот вариант


VM2VD>> pCart->GetShoppingCart(&var);


VM2VD>> VARIANT v_elem;

VM2VD>> VariantInit(&v_elem);
VM2VD>> v_elem.vt = VT_BSTR;
VM2VD>> for(long i=0; i<nCount; i++)
VM2VD>> {
VM2VD>> SafeArrayGetElement(pSA, &i, &v_elem);
VM2VD>> }

GS>Тебе вернется новое значение var и var.parray в нем не будет прежним pSA.



Большое спасибо за наводку!
Создал новый пойнтер на массив. Вот так все работает.

pCart->GetShoppingCart(&var);

SAFEARRAY *pSB = NULL;
pSB = var.parray;
long nElem = pSB->rgsabound[0].cElements;

VARIANT v_elem;
VariantInit(&v_elem);
v_elem.vt = VT_BSTR;
BSTR bstr;
for(long i=0; i<nElemt; i++)
{
    SafeArrayGetElement(pSB, &i, &v_elem);
    bstr = v_elem.bstrVal;
}

pCart->Release();
Re: Как разобрать Safearray из C++?
От: Leon_o  
Дата: 22.05.02 11:51
Оценка:
Здравствуйте vic_mx6_2.5_V6_dohc, Вы писали:

VM2VD>как воспроизвести на C++ разборку Визуал Бейсиковскго массива,

VM2VD>возвращаемого com-объектом?

Если установлен PSDK (август 2001), то можно использовать шаблонный класс T_SafeVector ,находится в SDK\include\T_SafeVector.h. Пример использования :


.idl :
// Возвращаем массив строк как SAFEARRAY и как VARIANT с SAFEARRAY
HRESULT GetStrings(SAFEARRAY(BSTR) *pStrings, VARIANT* pStringsAsVariant);



Так формируем данные :

STDMETHODIMP CArraySource::GetStrings(SAFEARRAY **pStrings, VARIANT* pStringsAsVariant)
{
    if(!pStrings || !pStringsAsVariant)
        return E_INVALIDARG;
    _bstr_tSafeVector v; // _bstr_tSafeVector определен в T_SafeVector.h
        // добавляем данные
    v.push_back(_bstr_t("abcd")); 
    v.push_back(_bstr_t("1234"));
        // Возвращаем как SAFEARRAY
    *pStrings = v.GetSafeArray();
        // Возвращаем как SAFEARRAY в VARIANT
        *pStringsAsVariant = v.GetVariant().Detach();     
        return S_OK;
}


Так получаем результат :

...
    CComPtr<IArraySource> spSource;
...
    SAFEARRAY *pArr = NULL;
    VARIANT   pArrAsVariant = _variant_t();
    hr = spSource->GetStrings(&pArr, &pArrAsVariant);
    if(SUCCEEDED(hr))
    {
        _bstr_tSafeVector v1(pArr);
        _variant_t  tmpValue(pArrAsVariant);
        _bstr_tSafeVector v2(tmpValue);
        _bstr_t tmp;
        // Получаем данные из первого массива
        tmp = v1[0]; // tmp == "abcd";
        tmp = v1[1];      // tmp == "1234"
        // Получаем данные из второго массива
        tmp = v2[0];      // tmp == "abcd"
        tmp = v2[1];      // tmp == "1234"; 
    }



Успехов!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.