
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Сообщ.
#1
,
|
|
|
Привет всем! Суть вопроса в следующем: у меня есть COM объект, через один из методов которого надо вернуть динамический массив структур (record'ов).
![]() ![]() type TUserList=record uid, compname, uname, cstat, utype: string; end; TULMas=array of TUserList; Сделать это видимо прийдется через OleVariant (обычный variant в библиотеке типов задать не получается). Делаю в 2 этапа: 1. Преобразовать массив к варианту. 2. преобразовать Variant к OleVariant. Проблема уже на первом этапе - не получается ни в какую преобразовать динамический массив к варианту! Делал так: ![]() ![]() aa: Variant; ULMas: TULMas; ..... DynArrayToVariant(aa, ULMas, inf); Выдает ошибку "invalid variant type conversion". Пробовал создать массив варианта и потом поэлементно перегнать в него мой динамический массив: ![]() ![]() Aa := VarArrayCreate([0, length(ULMas)-1], varVariant); for i:= 0 to length(ULMas)-1 do begin aa[i]:= ULMas[i]; end; Тогда просто говорит, что не совместимые типы variant и TUserList. Как тут быть? Заранее спасибо! PS: поиском я пользовался и ничего подходящего не нашел. Если вопрос уже обсуждался, буду очень признателен за ссылку или за ключевые слова для поиска. |
Сообщ.
#2
,
|
|
|
А кто тебе сказал, что в Variant и OLEVariant можно пихать что попало? Там есть свой список типов...
|
Сообщ.
#3
,
|
|
|
Я не спорю. Вопрос в том, как тогда задачу решить? Надо как-то передать этот динамический масив...
|
Сообщ.
#4
,
|
|
|
1. Берешь переменную OleVariant
2. Через VarArrayCreate делаешь в нем нужный массив 3. Делаешь VarArrayLock - копируешь память - Делаешь VarArrayUnlock (в finally конечно) 3а Или просто пользуешься этим массивом ![]() Добавлено А в случае, когда у тебя запись - увы, не так все просто. В варианте только простые типы есть, там SafeArray. Почему бы тебе не сделать отдельный интерфейс для передачи коллекции? |
Сообщ.
#5
,
|
|
|
Цитата Romkin @ Почему бы тебе не сделать отдельный интерфейс для передачи коллекции? имеешь в виду сделать отдельный инерфейс с той структурой, что у меня сейчас в record? Но я ведь все равно не смогу передавать массив, только элементы по отдельности... Или я неправильно понял? |
Сообщ.
#6
,
|
|
|
Не в том разделе спрашиваешь, есть ведь раздел для OLE/COM...
|
![]() |
Сообщ.
#7
,
|
|
uid, compname, uname, cstat, utype длиннее 255 символов?
если нет, то использовать ShortString или String[Х] и передавать просто массив байт |
![]() |
Сообщ.
#8
,
|
|
сохраняешь данные в Stream в каком хочешь формате и перегоняешь этот стрим в OleVariant по методике Romkin'a.
Добавлено Цитата Testudo @ есть ведь раздел для OLE/COM... олей тут слабо пахнет... |
Сообщ.
#9
,
|
|
|
Цитата SilverShield @ имеешь в виду сделать отдельный инерфейс с той структурой, что у меня сейчас в record? Но я ведь все равно не смогу передавать массив, только элементы по отдельности... Или я неправильно понял? По методу коллекции. На мой взгляд, строки так передавать удобнее. Объявляешь у себя в библиотеке типов record, и интерфейс с методами доступа к i-й записи (Минимум - в IEnumVariant, стандарт - см TCollection). Правда, с записями я не работал. А вот коллекцию делали, для передачи таблицы БД через интерфейс, там интерфейс доступа к коллекции интерфейсов ![]() Добавлено Просто надо понимать, что типы, объявленные в библиотеке типов, при ее использовании становятся известными. А там можно объявить и перечисление, и запись... |
Сообщ.
#10
,
|
|
|
![]() |
Сообщ.
#11
,
|
|
|
Цитата Romkin @ А вот коллекцию делали, для передачи таблицы БД через интерфейс, там интерфейс доступа к коллекции интерфейсов Romkin, можно здесь поподробней? Собственно это и есть изначальная задача: передать таблицу БД. Технология какая получается: создаю коллекцию (TColumns компонент TDBGrid), заполняю ее данными из моего запроса. При помощи методов типа GetRec(i) интерфейса выбираю по очереди из нее все записи, заталкиваю их в заготовленный record (интерфейса). А на другой стороне разгребаю эти record ы интерфеса... |
Сообщ.
#12
,
|
|
|
Так писал бы сразу универсальный набор интерфейсов. На будущее. А то потом еще одну табличку перегнать понадобится, мало ли
![]() И почему TDBGrid, неужели Fields датасета недостаточно? Сделай проще: реализуй интерфейс IMyRecords как минимум с методами навигации и BOF/EOF, а из его проперти Fields возвращай другой интерфейс, коллекцию полей. А у него методы Count и ItemName(i) - BSTR (WideString), ItemValue(i) - здесь Variant возвращай. Достаточно будет. Понятно, берешь этот интерфейс, и когда у его владельца next вызвано - его методы возвращают значения полей другой записи. Вот так и перегонишь. Кстати, а что, через ADO напрямую - никак? Там вообще ничего писать не надо, соединяешься - и вперед. |
Сообщ.
#13
,
|
|
|
Romkin, спасибо! Будет чем заняться в выходные
![]() Цитата Romkin @ Кстати, а что, через ADO напрямую - никак? Я с FireBird работаю, потому и пользую IBX, через ADO то да, можно просто _Recordset через тотже OleVariant передать. |
Сообщ.
#14
,
|
|
|
Если хватает возможеностей FreeIBProvider - то это будет самое простое. Ничего передавать не надо. Ничего писать не надо. Установить провайдер - и вперед. ADO легко работает через позднее связывание, из любого VBA спокойно подключишься.
В 1С небось? Там тоже элементарно доступ через ADO получить. Правда, в 8 версии они накосячили с СОМ, так что... |
Сообщ.
#15
,
|
|
|
Нет, это не 1С, это я сам намудрил
![]() |