На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Перегнать динамический массив , в OleVariant
    Привет всем! Суть вопроса в следующем: у меня есть COM объект, через один из методов которого надо вернуть динамический массив структур (record'ов).
    ExpandedWrap disabled
      type
        TUserList=record
           uid, compname, uname, cstat, utype: string;
           end;
       
           TULMas=array of TUserList;

    Сделать это видимо прийдется через OleVariant (обычный variant в библиотеке типов задать не получается). Делаю в 2 этапа: 1. Преобразовать массив к варианту. 2. преобразовать Variant к OleVariant.
    Проблема уже на первом этапе - не получается ни в какую преобразовать динамический массив к варианту!
    Делал так:
    ExpandedWrap disabled
      aa: Variant;
      ULMas: TULMas;
      .....
      DynArrayToVariant(aa, ULMas, inf);

    Выдает ошибку "invalid variant type conversion".
    Пробовал создать массив варианта и потом поэлементно перегнать в него мой динамический массив:
    ExpandedWrap disabled
      Aa := VarArrayCreate([0, length(ULMas)-1], varVariant);
            for i:= 0 to length(ULMas)-1 do
            begin
              aa[i]:= ULMas[i];
            end;

    Тогда просто говорит, что не совместимые типы variant и TUserList.
    Как тут быть? Заранее спасибо!

    PS: поиском я пользовался и ничего подходящего не нашел. Если вопрос уже обсуждался, буду очень признателен за ссылку или за ключевые слова для поиска.
      А кто тебе сказал, что в Variant и OLEVariant можно пихать что попало? Там есть свой список типов...
        Я не спорю. Вопрос в том, как тогда задачу решить? Надо как-то передать этот динамический масив...
          1. Берешь переменную OleVariant
          2. Через VarArrayCreate делаешь в нем нужный массив
          3. Делаешь VarArrayLock - копируешь память - Делаешь VarArrayUnlock (в finally конечно)
          3а Или просто пользуешься этим массивом :)

          Добавлено
          А в случае, когда у тебя запись - увы, не так все просто. В варианте только простые типы есть, там SafeArray. Почему бы тебе не сделать отдельный интерфейс для передачи коллекции?
            Цитата Romkin @
            Почему бы тебе не сделать отдельный интерфейс для передачи коллекции?

            имеешь в виду сделать отдельный инерфейс с той структурой, что у меня сейчас в record? Но я ведь все равно не смогу передавать массив, только элементы по отдельности... Или я неправильно понял?
              Не в том разделе спрашиваешь, есть ведь раздел для OLE/COM...
                uid, compname, uname, cstat, utype длиннее 255 символов?
                если нет, то использовать ShortString или String[Х] и передавать просто массив байт
                  сохраняешь данные в Stream в каком хочешь формате и перегоняешь этот стрим в OleVariant по методике Romkin'a.

                  Добавлено
                  Цитата Testudo @
                  есть ведь раздел для OLE/COM...

                  олей тут слабо пахнет...
                    Цитата SilverShield @
                    имеешь в виду сделать отдельный инерфейс с той структурой, что у меня сейчас в record? Но я ведь все равно не смогу передавать массив, только элементы по отдельности... Или я неправильно понял?

                    По методу коллекции. На мой взгляд, строки так передавать удобнее. Объявляешь у себя в библиотеке типов record, и интерфейс с методами доступа к i-й записи (Минимум - в IEnumVariant, стандарт - см TCollection). Правда, с записями я не работал.
                    А вот коллекцию делали, для передачи таблицы БД через интерфейс, там интерфейс доступа к коллекции интерфейсов :)

                    Добавлено
                    Просто надо понимать, что типы, объявленные в библиотеке типов, при ее использовании становятся известными. А там можно объявить и перечисление, и запись...
                      :wacko: Наверное когда начну делать, станет понятней... Спасибо всем!
                        Цитата Romkin @
                        А вот коллекцию делали, для передачи таблицы БД через интерфейс, там интерфейс доступа к коллекции интерфейсов

                        Romkin, можно здесь поподробней? Собственно это и есть изначальная задача: передать таблицу БД.
                        Технология какая получается: создаю коллекцию (TColumns компонент TDBGrid), заполняю ее данными из моего запроса. При помощи методов типа GetRec(i) интерфейса выбираю по очереди из нее все записи, заталкиваю их в заготовленный record (интерфейса). А на другой стороне разгребаю эти record ы интерфеса...
                        Сообщение отредактировано: SilverShield -
                          Так писал бы сразу универсальный набор интерфейсов. На будущее. А то потом еще одну табличку перегнать понадобится, мало ли :)
                          И почему TDBGrid, неужели Fields датасета недостаточно?
                          Сделай проще: реализуй интерфейс IMyRecords как минимум с методами навигации и BOF/EOF, а из его проперти Fields возвращай другой интерфейс, коллекцию полей. А у него методы Count и ItemName(i) - BSTR (WideString), ItemValue(i) - здесь Variant возвращай. Достаточно будет. Понятно, берешь этот интерфейс, и когда у его владельца next вызвано - его методы возвращают значения полей другой записи. Вот так и перегонишь.
                          Кстати, а что, через ADO напрямую - никак? Там вообще ничего писать не надо, соединяешься - и вперед.
                            Romkin, спасибо! Будет чем заняться в выходные :)
                            Цитата Romkin @
                            Кстати, а что, через ADO напрямую - никак?

                            Я с FireBird работаю, потому и пользую IBX, через ADO то да, можно просто _Recordset через тотже OleVariant передать.
                              Если хватает возможеностей FreeIBProvider - то это будет самое простое. Ничего передавать не надо. Ничего писать не надо. Установить провайдер - и вперед. ADO легко работает через позднее связывание, из любого VBA спокойно подключишься.
                              В 1С небось? Там тоже элементарно доступ через ADO получить. Правда, в 8 версии они накосячили с СОМ, так что...
                                Нет, это не 1С, это я сам намудрил :)
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0685 ]   [ 15 queries used ]   [ Generated: 18.07.25, 00:35 GMT ]