Как передать процедуре переменную неизвестного ей типа?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Как передать процедуре переменную неизвестного ей типа?

Сообщение 0xy » 14.01.2007 (Вс) 4:18

Есть некая поцедура.
Её задача--ТУПО записывать в файл всё, что ей передают.
Передавать ей я хочу структуры РАЗЛИЧНЫХ типов.
ДЛИНА СТРУКТУР НЕИЗВЕСТНА (Len не катит!), так что с VarPtr не получится.
Процедура эта небольшая, но и не на пару строчек (проверяет атрибуты, уникальность имени, обрабатывает ошибки...)

В общем, пока приходится клешировать эту процедуру (создавать свой экземпляр для каждого типа данных) Код быстро засоряется :(

Wolfie
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 213
Зарегистрирован: 06.03.2006 (Пн) 18:52
Откуда: Россия, Москва, СЗАО

Сообщение Wolfie » 14.01.2007 (Вс) 23:28

А ТИП VARIANT чем здесь не подходит?
Ну вот насчет записи - имеет смысл тогда писать Binary файлы, ведь Put #F поддерживает запись чего угодно...
это ИМХО, поправьте если нельзя :)
··•··•••··•··••·•·•·•···••·•••···•···•••·•··•·•··
C:\> per asper ad astra
'ASTRA' answer: Path 'ASPER' Not Found
684 Errare humanum est!
C:\> _

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 15.01.2007 (Пн) 10:20

Put тоже должна знать длину для записи чего угодно...
Лучший способ понять что-то самому — объяснить это другому.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.01.2007 (Пн) 10:49

Вопросы автору:

1. Насчет структур различных типов неизвестной длины. А как так получается, что длина их неизвестна?
2. А какова собственно задача стоит перед автором. Может быть выяснив задачу, подскажем путь?
Весь мир матрица, а мы в нем потоки байтов!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 15.01.2007 (Пн) 11:40

разбирай структуру в байтовый массив и сохраняй его на диск

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 15.01.2007 (Пн) 16:08

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

Через VARIANT не передать пользовательский тип и вообще его никак универсально не передать. Через Variant'ы можно передвать классы и делать enum их членов, для типов не сработает.

Пользовательскую структуру никак не передать универсально - в них могут быть строки - а следовательно узнать их длину и передать адрес не удасться и enum членов у них не сделать. Значит подругому никак - только "клешировать эту процедуру (создавать свой экземпляр для каждого типа данных)"

Могу предложить сделать внешнюю библиотеку и объявить её как parameter as Any, но если в структурах есть строки или объекты - то узнать где - что извне будет невозможно, так же как и узнать имя структуры...
Программисты не глючат - глючат компиляторы...

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 15.01.2007 (Пн) 17:19

Пользовательскую структуру никак не передать универсально - в них могут быть строки - а следовательно узнать их длину и передать адрес не удасться и enum членов у них не сделать.


Ну почему же нельзя, во многих языках есть функции для преобразования структур в текстовую строку и обратно в структуру.
Называется этот процесс - сериализация пользовательских типов.
Например в PB для этого служит оператор TYPE SET.
Вот пример упаковки пользовательского типа со строками, а ведь можно сериализовать и вложенные структуры! Это вообще отдельная и интересная тема. Другое дело, что все эти радости не реализованы в VB.


Код: Выделить всё
Type udt1
  x As String * 12
  y As Long
  z As Integer
End Type


Function PBMain
  Dim u1 As udt1
  Dim u2 As String

  u1.x = "ABC"
  u1.y=1
  u1.z=2

  u2=Space$(Len(u1))
  Type Set u2 = u1 'упаковываем пользовательску структуру в текстовую строку
  MsgBox u2
End Function

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 15.01.2007 (Пн) 17:52

Дык то в PB(в числе недостатков которого - непонимание юникода). В VB есть только один способ запихнуть структуру в Variant - объявить в глобальном классе. Что возможно лишь в ActiveX. Хотя ничто не мешает сделать ActiveX EXE, который будет работать как обычный - просто не делать публичных создаваемых классов.
Изображение

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 15.01.2007 (Пн) 17:55

Структуры будут определены заранее и тобой?

Если да, то введи в структуру доппеременную, содержащую ее [структуры] длину. Записываешь данные - прибавляй. Очищаешь - убавляй.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 15.01.2007 (Пн) 18:02

Если да, то введи в структуру доппеременную, содержащую ее [структуры] длину. Записываешь данные - прибавляй. Очищаешь - убавляй.


но ведь у структуры всегда фиксированный размер, зачем эта переменная? :D

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 15.01.2007 (Пн) 18:11

В соседнем топике автор приводил пример структуры...

Если у структуры фиксированный размер, то он находится очень и очень просто :)

Код: Выделить всё
Private Type abc
    a(1 To 10) As Long
End Type

Private Sub Form_Load()
    Dim var As abc
   
    MsgBox LenB(var)
End Sub


Длина будет равна 10*4.

А для нашего случая в MSDN есть пометочка...
Note
Len may not be able to determine the actual number of storage bytes required when used with variable-length strings in user-defined data types.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.01.2007 (Пн) 21:32

Её задача--ТУПО записывать в файл всё, что ей передают.
Передавать ей я хочу структуры РАЗЛИЧНЫХ типов.
ДЛИНА СТРУКТУР НЕИЗВЕСТНА
Вот именно сейчас я пишу заказ, в котором мне требуется записывать в файл структуры различной длинны. Т.е. ситуация такая-же как и у тебя. Я решил проблему так: в начале каждой структуры ОБЯЗАТЕЛЬНО присутствует параметр типа BYTE (ну если типов структрур будет больше 256, тогда тип придется сменить... :wink: ) который определяет тип структуры. По значению этой переменной я и определяю, сколько байт следует писать в файл. Ведь все структуры ты заполняешь в СВОЕЙ программе! Или программист не ищет легких путей? Поверь, динамическое распознование длинны структуры отнимет намного больше времени и сил, чем приведенный выше способ. Тебе оно надо? :wink:
А я все практикую лечение травами...

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Сообщение 0xy » 19.01.2007 (Пт) 5:40

Antonariy писал(а):Put тоже должна знать длину для записи чего угодно...

Ну да, узнает ее в процессе записи :)

!Viper!
1. Насчет структур различных типов неизвестной длины. А как так получается, что длина их неизвестна?

Ну, не подсчитывал вручную ее ни кто. Мало ли, сколько слов в каждой строке записано.
2. А какова собственно задача стоит перед автором.

С этой проблемой я сталкивался в различных задачах.
Т.е. мне необходима сериализация структур, о которой пишет jangle

jangle писал(а):u2=Space$(Len(u1))
Type Set u2 = u1 'упаковываем пользовательску структуру в текстовую строку

А в PB что, и Len правильная?
А реально ли самому написать процедуру этого Type Set? (а заодно и правильного Len)?

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 19.01.2007 (Пт) 10:04

0xy
Len считает правильно. Длина структуры всегда постоянна, если в структуре есть ссылочные типы, то их содержимое ведь лежит не в структуре, а где-то в другом месте.

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Сообщение 0xy » 19.01.2007 (Пт) 22:08

_ae_ писал(а):0xy
Длина структуры всегда постоянна, если в структуре есть ссылочные типы, то их содержимое ведь лежит не в структуре, а где-то в другом месте.

Действительно, я как-то не подумал об этом.
Тогда должно сработать так:
Код: Выделить всё
Type UserType
................
End Type
Dim UT as UserType, UTLink&, UTLen&, UTType$

UTLink=VarPtr(UT)
UTLen=Len(UT)
UTType="UserType"
Write2File(UTLink, UTLen, UTType)
................................
Function Write2File(UTLink&, UTLen&, UTType$)
dim UT as ' А КАК ПОДСТАВИТЬ СЮДА ЗНАЧЕНИЕ UTType ???
RtlMoveMemory UT, UTLink, UTLen
................................
End Function

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 19.01.2007 (Пт) 22:42

Нет, так работать не должно
Вообще, эти рассуждения твои и Амеда о структурах нефиксированной длины наводят на мысли о неипонимании сути некоторых вещей. Невозмжно одним CopyMemory сериализовать структуру, которая содержит ссылки на другие области в памяти. Не надо искать такой код - его не существует.

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Сообщение 0xy » 21.01.2007 (Вс) 19:49

_ae_ писал(а):Невозмжно одним CopyMemory сериализовать структуру, которая содержит ссылки на другие области в памяти.

Это понятно. А вот ты меня не понял ;)
Мой пример НЕ сериализует структуру, а лишь передает ее в процедуру Write2File. Именно это и должно было сработать. Только я не знаю, как подставить значение строки UTType оператору Dim as?
Что касается сериализации, то пака единственный известный мне способ--это запись структуры в tmp-файл и чтение строки из него.

ЗЫ
0xy писал(а):А реально ли самому написать процедуру этого Type Set?


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

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

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

    TopList