Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> использование VARIANT SAFEARRAY, массив VARIANT 
V
    Опции темы
елки
Дата 11.12.2016, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.1.2016

Репутация: нет
Всего: нет



Всем привет. Сейчас работаю с некоторой динамической библиотекой(*.dll). Пытаюсь из этой dll использовать  некую функцию GetTitleIDList. Прототип функции в Visual C++ выглядит так GetTitleIDList(VARIANT_BOOL , int, int, int*, VARIANT*,VARIANT*).
В документации к  dll эта функция описывается так:
    This method retrieves two arrays which contain the IDs and titles of all entities (in the selected ID range) with the same type as the current object. 
    GetTitleIDList( bIncludeID, minID, maxID, count, listID, listTITLE )

    Input: 
  •  BOOL bIncludeID
     If True, the  titles are in the form “ID..title” (for example, “1..Steel”. If False, only the title, without the ID or separator is returned.
     
  •  INT4 minID
     The minimum and maximum entity IDs to retrieve. You can set  minID=maxID=0 to retrieve all available entities.
     
     
  •  INT4 maxID

    Output:
     
  •  INT4 count
     The number of entities retrieved. This is the number of entries in listID and listTITLE.
     
  •  INT4 listID[0..count-1]
     The IDs of the available entities.
     
    STRING listTITLE[0..count-1]
     The titles of the available entities. If the entity does not have a title, the string “Untitled” will be returned.
     
    Return Code:
     
  • [FE_FAIL=0 FE_OK=-1 
     This function is only available for entity types that have titles (Mate­rial, Property, View, etc)
В документации приведен пример на Visual BAsic
Код

‘Attach to FEMAP........................
Dim femap As Object
Set femap = GetObject(, "femap.model")

‘Look at Output Set 3...................
Dim oc As Object
Set oc = femap.feOutputSet()
oc.Get (3)
Dim od As Object
Set od = oc.Vector(1)

Dim rc As Integer
Dim Count As Long
Dim ID As Variant
Dim Title As Variant
Dim Row As Integer

‘Retrieve ID and Title of all available Output Vectors...
rc = od.GetTitleIDList(False, 0, 0, Count, ID, Title)
‘ Display list in cells of a spreadsheet.................
For Row = 1 To Count
  Worksheets(1).Cells(Row, 1).Value = ID(Row - 1)
  Worksheets(1).Cells(Row, 2).Value = Title(Row - 1)
Next Row

Теперь как я пытаюсь это использовать.
Код

        int count;
    SAFEARRAY *TitleArray;
    SAFEARRAY *IDArray;
        BSTR str;
    TitleArray=SafeArrayCreateVector(VT_BSTR,0,9);
    IDArray=SafeArrayCreateVector(VT_I4,0,9);
         if(TitleArray==0)return 0;
    if(IDArray==0)return 0;
        if(pEntity->GetTitleIDList(true,0,0, &count,  (VARIANT*) IDArray, (VARIANT*) TitleArray)==-1){
        for (long i=0; i<count;i++){
             if(SafeArrayGetElement(TitleArray,&i,&str){
                MessageBox(0,str,str,0); // в этом месте планировалось вызвать SendMessage(hList, LB_ADDSTRING,0, (LPARAM)str); 
              }      
            }
       }
 В сообщении MessageBox выводятся иероглифы вместо строк на английском языке.
 пробовал использовать VARIANT
Код

        VARIANT ListTitle
        int count;
    SAFEARRAY *TitleArray;
    SAFEARRAY *IDArray;
        BSTR str;
    TitleArray=SafeArrayCreateVector(VT_BSTR,0,9);
    IDArray=SafeArrayCreateVector(VT_I4,0,9);
         if(TitleArray==0)return 0;
    if(IDArray==0)return 0;
        ListTitle.vt=VT_ARRAY|VT_BSTR;
        ListTitle.parray=TitleArray;
        if(pEntity->GetTitleIDList(true,0,0, &count,  (VARIANT*) IDArray, &ListTitle)==-1){
        for (long i=0; i<count;i++){
              //тут пока не понятно как из VARIANT ListTitle извлечь массив строк и вывести их хотя бы в MessageBox
              }      
            }
       }

 Подскажите в чём моя ошибка и как лучше исправить?

Это сообщение отредактировал(а) елки - 11.12.2016, 19:45
PM MAIL   Вверх
feodorv
Дата 11.12.2016, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



А что у Вас с UNICODE?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
елки
Дата 11.12.2016, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.1.2016

Репутация: нет
Всего: нет



Цитата(feodorv @  11.12.2016,  20:56 Найти цитируемый пост)
А что у Вас с UNICODE? 

Я специально никакие настройки  не выставлял. Часть проекта автоматически сгенирирована в visual studio 2010. 

PM MAIL   Вверх
feodorv
Дата 11.12.2016, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Ну так у Вас по умолчанию может быть выставлено UNICODE, а GetTitleIDList() может возвращать простое ASCII. Вот у Вас и иероглифы в MessageBox().

PS Такое возможно, но не обязательно. Но не мешает проверить)))

Добавлено через 29 секунд
Попробуйте MessageBoxA().


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
елки
Дата 11.12.2016, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.1.2016

Репутация: нет
Всего: нет



feodorv, попробовал не получилось. думаю дело не в кодировке. предпоследнее значение в этой функции вообще целое число и тоже не хочет выводиться. пробовал вот такой код.
Код

long n=-1;
for(long i-0;i<count;i++)
if(SafeArrayGetElement(IDArray,&i,&n)){
 почему-то получается, что n так и остается -1 и никак не меняется. ну, если поставлю n=-10, то так и останется -10...
}

PM MAIL   Вверх
vol4ek
Дата 11.12.2016, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: 0
Всего: 0



не увидел функции VariantInit
PM MAIL ICQ   Вверх
миг
Дата 12.12.2016, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 15.9.2008

Репутация: нет
Всего: 1



VariantInit - устанавливает флаг VT_EMPTY Это означает пустой вариант. Если хотим поместить данные, то должны изменить флаг VT_тип данных которые нужно поместить в вариант. Можно теоретически сделать пустой вариант и пусть функция GetTitleIdList сама попробует установить ей нужный флаг и записать данные.
--------------------
Oaks may fall when reeds stand the storm.
PM MAIL   Вверх
vol4ek
Дата 12.12.2016, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: 0
Всего: 0



Цитата(миг @ 12.12.2016,  06:46)
VariantInit - устанавливает флаг VT_EMPTY. Можно теоретически сделать пустой вариант и пусть функция GetTitleIdList сама попробует установить ей нужный флаг и записать данные.

я всегда так и делал и проблем с этим типом никогда небыло.
PM MAIL ICQ   Вверх
feodorv
Дата 12.12.2016, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



А я вот соглашусь с vol4ek. Как-то это все жестко выглядит:
Цитата(елки @  11.12.2016,  19:43 Найти цитируемый пост)
(VARIANT*) IDArray, (VARIANT*) TitleArray)

Я так понимаю, что в GetTitleIDList() отправляются пустые VARIANT, а возвращаются заполненные, которые потом высвобождать нужно будет.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
миг
Дата 12.12.2016, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 15.9.2008

Репутация: нет
Всего: 1



vol4ek, VariantInit эквивалентно записи
Код

VARIANT t;
t.vt=VT_EMPTY;

А если известно какие типы данных будут хранится в переменной, то почему нельзя сразу записать t.vt=VT_ARRAY и т.д.? Другое дело вызываемая функция могла установить другой флаг.

Добавлено через 1 минуту и 21 секунду
Цитата(feodorv @  12.12.2016,  09:22 Найти цитируемый пост)
Я так понимаю, что в GetTitleIDList() отправляются пустые VARIANT, а возвращаются заполненные, которые потом высвобождать нужно будет. 

Да именно так. Если верить описанию этой функции.
--------------------
Oaks may fall when reeds stand the storm.
PM MAIL   Вверх
vol4ek
Дата 12.12.2016, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: 0
Всего: 0



Цитата(миг @ 12.12.2016,  09:57)
vol4ek, VariantInit эквивалентно записи
Код

VARIANT t;
t.vt=VT_EMPTY;

А если известно какие типы данных будут хранится в переменной, то почему нельзя сразу записать t.vt=VT_ARRAY и т.д.? Другое дело вызываемая функция могла установить другой флаг.

Добавлено @ 09:58
Цитата(feodorv @  12.12.2016,  09:22 Найти цитируемый пост)
Я так понимаю, что в GetTitleIDList() отправляются пустые VARIANT, а возвращаются заполненные, которые потом высвобождать нужно будет. 

Да именно так. Если верить описанию этой функции.

я вкурсе чем занимается VariantInit() и думаю с флагом VT_EMPTY и надо работать. пусть GetTitleIDList сама ставит нужные флаги. Наврятли функцию инициализации зря придумали.
PM MAIL ICQ   Вверх
елки
Дата 12.12.2016, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.1.2016

Репутация: нет
Всего: нет



vol4ek, вот если написать так
Код

VARIANT* var1;
VARIANT* var2;
VariantInit(var1);
VariantInit(var2);
int count;
pEntity->GetTitleIDList(true,0,0,&count, var1, var2);

то при вызове функции программа падает и запускается отладчик.
PM MAIL   Вверх
елки
Дата 12.12.2016, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.1.2016

Репутация: нет
Всего: нет



Всем спасибо. у меня наконец-то получилось, то что нужно. 
Код

int count;
VARIANT listTitle;
SAFEARRAY *IDArray;
SAFEARRAY* Test;
BSTR str;
IDArray=SafeArrayCreateVector(VT_I4,0,9);
if(pEntity->GetTitleList(true, 0, 0, &count, (VARIANT*) IDArray, &listTitle)==-1){
  for(long i=0; i<count; i++){
      Test=listTitle.parray;
       if(!SafeArrayGetElement(Test,&i,&str)) MessageBox(0,str,str,0);
 }
}

PM MAIL   Вверх
xvr
Дата 13.12.2016, 10:53 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Неправильно. Работает у вас чисто случайно - места в IDArray хватило на VARIANT и вы его (IDArray) потом не используете
Вариант из предыдущего сообщения был почти правильный. Надо так:
Код

VARIANT var1;
VARIANT var2;
VariantInit(&var1);
VariantInit(&var2);
int count;
pEntity->GetTitleIDList(true,0,0,&count, &var1, &var2);

PM MAIL   Вверх
миг
Дата 27.12.2016, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 15.9.2008

Репутация: нет
Всего: 1



Кстати можно еще использовать 
Код


 CComVariant var1

Но VARIANT тоже сработает
--------------------
Oaks may fall when reeds stand the storm.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0859 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.