Объявление alias функциий

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
mikhail_g
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 30.09.2011 (Пт) 8:39

Объявление alias функциий

Сообщение mikhail_g » 30.09.2011 (Пт) 9:06

Добрый день! написал простую программу ОРС клиента с использование библиотеки типов которая содержится в opcdaauto.dll. В этой самой tlb есть функции, которые служат для записи/чтения данных из ОРС сервера. Чтение сразу нескольких переменных, а то и массивов. Набор функции относится к объекту OPCGroup. Однако здесь есть свой минус: функция читает все переменные и записывает их в массив типа Variant. У меня передается только байтовый массив, каждый элемент которого записывается в VB как variant, а это аж 16 байт! При современных объемах RAM в этом, в принципе, нет ничего страшного, однако эта проблема меня коробит. Пробовал пофиксить tlb, но там надо скачать кучу header файлов с описание нетипизированных типов данных (того же OPCGroup или OPCServer).
Возможно, кто то подскажет как изменить выходной параметр функции (Value) с variant на byte. Ниже приведена экспортируемая ф-ция из idl:
Код: Выделить всё
        HRESULT SyncRead(
                        [in] short Source,
                        [in] long NumItems,
                        [in] SAFEARRAY(long)* ServerHandles,
'Вот это параметр:
                        [out] SAFEARRAY(VARIANT)* Values,
                        [out] SAFEARRAY(long)* Errors,
                        [out, optional] VARIANT* Qualities,
                        [out, optional] VARIANT* TimeStamps);


P.S. возможно можно объявить alias для это ф-ции в каком нибудь модуле, но я только сейчас об этом подумал!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Объявление alias функциий

Сообщение Хакер » 30.09.2011 (Пт) 9:12

Если сама функция SyncRead, её реализация, её код ожидает получить ссылку на массив Variant-ов, то можно хоть что делать с TLB и как угодно переобъявлять функцию.

Суть функции от этого не изменится: она всё равно будет ожидать ссылку на массив вариантов, и именно это нужно будет передавать для правильной работы.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

mikhail_g
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 30.09.2011 (Пт) 8:39

Re: Объявление alias функциий

Сообщение mikhail_g » 30.09.2011 (Пт) 9:44

К сожалению исходника на С++, скорее всего на нем описаны функции, у меня нету. Скачать тоже думаю не особо реально.
Все равно спасибо! Не буду пробовать заранее проигрышный вариант.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Объявление alias функциий

Сообщение Vi » 30.09.2011 (Пт) 12:32

mikhail_g писал(а):Однако здесь есть свой минус: функция читает все переменные и записывает их в массив типа Variant. У меня передается только байтовый массив, каждый элемент которого записывается в VB как variant, а это аж 16 байт! При современных объемах RAM в этом, в принципе, нет ничего страшного, однако эта проблема меня коробит. Пробовал пофиксить tlb, но там надо скачать кучу header файлов с описание нетипизированных типов данных (того же OPCGroup или OPCServer).

Возможно, кто то подскажет как изменить выходной параметр функции (Value) с variant на byte.

Функция читает много переменных, но значение каждой переменной хранится в одном Variant-е в массиве Variant-ов. Таким образом, весь массив байт от одной переменной будет лежать в одном элементе массива и будет именно массивом байт. И ничего выдумывать не нужно.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 30.09.2011 (Пт) 12:39

Vi писал(а):Таким образом, весь массив байт от одной переменной будет лежать в одном элементе массива и будет именно массивом байт.

Что-то сомневаюсь.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Объявление alias функциий

Сообщение Хакер » 30.09.2011 (Пт) 12:46

Qwertiy писал(а):Что-то сомневаюсь.

Почему? Я не знаю, что такое OPC (кроме Opel Performance Center), и что за функции, но вполне возможно в вариант-переменную засунуть байтовый массив.

Таким образом, на выходе будет массив массовов байт.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 30.09.2011 (Пт) 12:51

Хакер писал(а):Почему?

Ведь массив из одной переменной, содержащей массив байтов отличается по использованию от массива, в котором по байту в элементе?
В первом сообщении написано:
mikhail_g писал(а):У меня передается только байтовый массив, каждый элемент которого записывается в VB как variant, а это аж 16 байт!


Хотя, сейчас заметил, что передаётся указатель на Variant, т. е. не факт, что это именно массив.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Объявление alias функциий

Сообщение Хакер » 30.09.2011 (Пт) 12:58

Qwertiy писал(а):Ведь массив из одной переменной, содержащей массив байтов отличается по использованию от массива, в котором по байту в элементе?

Причём тут «из одной переменной» и «по использованию от массива, в котором по байту в элементе»?

У тебя будет
Dim arrayOfArrays() As Variant
Нужно передавать ссылку вот именно на этот массив. Каждый элемент такого массива — вариант-значение. Но не просто вариант-значение, а само по себе — другой массив (байтовый массив).

Код: Выделить всё
TypeName(arrayOfArrays) => Variant()
TypeName(arrayOfArrays(N)) => Byte()
TypeName(arrayOfArrays(N)(M)) => Byte
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 30.09.2011 (Пт) 13:05

Хакер писал(а):Но не просто вариант-значение, а само по себе — другой массив (байтовый массив).

В таком случае, для обращения к конкретному байту используются два индекса. Если же каждый байт помещён в отдельный variant, то только один индекс. Это я и имел в виду под "отличается по использованию".

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Объявление alias функциий

Сообщение Хакер » 30.09.2011 (Пт) 13:06

Qwertiy писал(а):В таком случае, для обращения к конкретному байту используются два индекса. Если же каждый байт помещён в отдельный variant, то только один индекс.

Так думал топикстартер и я по его описанию. Но Vi то ли просто предположил, то ли утверждает, что первый массив используется не для байтов, а для фрагментов. Если так, то первый индекс — индекс фрагмента, а второй индекс — индекс байта во фрагменте.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Объявление alias функциий

Сообщение Vi » 30.09.2011 (Пт) 14:50

Хакер писал(а):
Qwertiy писал(а):В таком случае, для обращения к конкретному байту используются два индекса. Если же каждый байт помещён в отдельный variant, то только один индекс.

Так думал топикстартер и я по его описанию. Но Vi то ли просто предположил, то ли утверждает, что первый массив используется не для байтов, а для фрагментов. Если так, то первый индекс — индекс фрагмента, а второй индекс — индекс байта во фрагменте.

Это функция такая - вернуть значения заданных переменных.
Вот есть переменные a as string = "aaa", b as long = 777, c(10) As Byte = "байты". Их нужно вернуть, поскольку функция их просит. Поэтому v(2) as variant и v(0)=a, v(1)=b, v(2)=c и возвращаем этот массив.

Никто не мешает снова взять массив обратно из элемента массива и работать с одиночной скобкой.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

mikhail_g
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 30.09.2011 (Пт) 8:39

Re: Объявление alias функциий

Сообщение mikhail_g » 03.10.2011 (Пн) 8:57

На самом деле весь массив байт, переданный с сервера, запишется в VB как массив variant, и каждый байт исходного массива станет вариантом конечного (т.е. размерность массива не изменится). Но, как правильно сказал Хакер, этот массив станет вложенным массивлм в исходный под номером 1, и для обращения к его элементам надо будет использовать два индекса, соответственно.
Вот как она работает:
Код: Выделить всё
'если исходный массив такой: sourceArr[10] as byte
Dim ReadValues() As Long  'массив типа вариант, в который мы запишем исходный
ConnectedGroup.SyncRead 1, ItemCount, ServerHandles(), ReadValues, Errors'функция читающая из ОРС сервера

'Обращение к 5 элементу конечного массива
Readvalues[1][5]=128
'Это равносильно следующему sourceArr[5]=128



Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Объявление alias функциий

Сообщение Vi » 04.10.2011 (Вт) 9:19

mikhail_g писал(а):На самом деле весь массив байт, переданный с сервера, запишется в VB как массив variant, и каждый байт исходного массива станет вариантом конечного (т.е. размерность массива не изменится). Но, как правильно сказал Хакер, этот массив станет вложенным массивом в исходный под номером 1, и для обращения к его элементам надо будет использовать два индекса, соответственно.

Хакер также сказал, как проверить, записывается ли массив байт как массив вариантов или нет.
Код: Выделить всё
TypeName(arrayOfArrays) => Variant()
TypeName(arrayOfArrays(N)) => Byte()
TypeName(arrayOfArrays(N)(M)) => Byte
Где arrayOfArrays является в твоих обозначениях Readvalues.
Вот если будет TypeName(arrayOfArrays(N)) => Variant(), тогда будет справедливо, что "весь массив байт, переданный с сервера, запишется в VB как массив variant, и каждый байт исходного массива станет вариантом конечного". А пока это - всё домыслы.

Я много лет работаю с СОМом и никогда не видел, чтобы СОМ (а это почти что ОРС) сам по себе изменял тип массивов. Наоборот, это всегда являлось проблемой - перевести массив с одним типом данных в другой.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

mikhail_g
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 30.09.2011 (Пт) 8:39

Re: Объявление alias функциий

Сообщение mikhail_g » 04.10.2011 (Вт) 19:48

Я хотел бы внести ясность. У меня следующая конфигурация системы: есть ПК, на котором установлен ОРС сервер, в котором находится массив байт (как он туда попадает не имеет значения). Далее клиент, написанный на VB с использованием tbl (OPC DA Wrapper), устанавливает связь, и по какому то событию (например по истечению таймера), считывает этот массив с использованием функции, которая экспортируется из этой самой tlb, а именно:
Код: Выделить всё
ConnectedGroup.SyncRead 1, ItemCount, ServerHandles(), ReadValues, Errors'функция читающая из ОРС сервера
. Эта функция требует в качестве параметра массив типа variant, что следует из ее описание в idl:
Код: Выделить всё
        HRESULT SyncRead(
                        [in] short Source,
                        [in] long NumItems,
                        [in] SAFEARRAY(long)* ServerHandles,
'Вот это параметр:
                        [out] SAFEARRAY(VARIANT)* Values,
                        [out] SAFEARRAY(long)* Errors,
                        [out, optional] VARIANT* Qualities,
                        [out, optional] VARIANT* TimeStamps);

Vi писал(а):А пока это - всё домыслы


Почему домысл? Программа написана и работает. Функция, описанная выше, работает именно так, как я описал своем предыдущем посте. Это точно.

Vi писал(а):Я много лет работаю с СОМом и никогда не видел, чтобы СОМ (а это почти что ОРС) сам по себе изменял тип массивов.


И кое что уточнить: в моей программе я никаких интерфейсов DCOM не создавал и не использовал в явном виде. Все это делают закрытые функции в классе ОРС. Чтобы мне установить связь, достаточно написать OPCServer.Connect (IDPC, IDServer), где IDPC - IP адрес или, в случае внутренней сети, имя компьютера, а IDServer - имя ОРС сервера. Как, и по средствам каких интерфейсов, DCOM далее общаются между собой, я не знаю. Поэтому я не имею понятия о том, в каком виде ф-ция получает данные из ОРС сервера, я лишь утверждаю, что мне она предоставляет их в виде массива вариантов, в котором каждый байт неявно приводится к типу вариант, и становится одним из элементов массива. Так же, как если бы исходным был не массив байт а массив слов. Каждое слово привелось бы неявно к варианту, и стало бы так же элементом массива. Это проверено опытным путем. Вот ссылка на документацию, описывающую используемую tlb:
http://www-ad.fnal.gov/controls/opc/OPC_DA_Auto_2.02_Specification.pdf

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Объявление alias функциий

Сообщение Vi » 05.10.2011 (Ср) 9:51

mikhail_g писал(а):Я хотел бы внести ясность...
...Поэтому я не имею понятия о том, в каком виде ф-ция получает данные из ОРС сервера, я лишь утверждаю, что мне она предоставляет их в виде массива вариантов, в котором каждый байт неявно приводится к типу вариант, и становится одним из элементов массива. Так же, как если бы исходным был не массив байт а массив слов. Каждое слово привелось бы неявно к варианту, и стало бы так же элементом массива. Это проверено опытным путем.

Входной массив вариантов требует сама функция, её документация, и это положение не может быть изменено, поэтому вопроса для дискуссии просто нет. Ты должен передавать массив вариантов.

А вот по поводу того, что вернет функция, - это ты не понимаешь. Она вернет массив вариантов, каждым элементом которого будет различные данные. Там могут быть числа, строки текста, массивы различных данных (как они представлены внутри ОРС сервера) и многое другое. Если ты утверждаешь, что хранится массив байт, то этот массив байт тебе и вернётся в соответствующем элементе массива вариантов, который ты передал в функцию. Никаких преобразований массива байт в массив вариантов никто делать не будет.

В той же документации есть обратная функция к SyncRead - SyncWrite, в которой те же самые параметры, и там есть пример, заполняющий этот массив вариантов для передачи на ОРС сервер. Вот он:
Код: Выделить всё
For ServerIndex = 1 to NumItems
‘ set up which items to be written
ServerHandles(ServerIndex) = AnOPCItemServerHandles(ServerIndex)
Values(ServerIndex) = ServerIndex * 2 ‘ any random value for this example would suffice
Next ServerIndex
OneGroup.SyncWrite NumItems, ServerHandles, Values, Errors

Если ты положишь вместо числа массив байт, то он пойдет в функцию как массив байт и вернется потом через SyncRead таким же массивом байт, а не вариантов.

Мораль всей дискуссии топика - ничего тебе не нужно делать. Всё уже сделано. Никаких оптимизаций по памяти не сделать. И нужно смириться и удушить свою жабу.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

mikhail_g
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 30.09.2011 (Пт) 8:39

Re: Объявление alias функциий

Сообщение mikhail_g » 05.10.2011 (Ср) 18:08

Vi писал(а): Она вернет массив вариантов, каждым элементом которого будет различные данные. Там могут быть числа, строки текста, массивы различных данных (как они представлены внутри ОРС сервера) и многое другое.


Спасибо, теперь понял. и согласен с вами!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 47

    TopList  
cron