Получить значения ключей коллекции

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Получить значения ключей коллекции

Сообщение The trick » 11.03.2014 (Вт) 11:56

В примере можно получить значения ключей коллекции по индексу.
Код: Выделить всё
Option Explicit
   
Private Declare Function GetMem4 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
   
Private Sub Form_Load()
     Dim Col As Collection, i As Long
     
     Set Col = New Collection
     
     Col.Add "ssss", "item1"
     Col.Add "ssss", "item2"
     Col.Add "ssss", "item3"
     Col.Add "ssss", "item4"
     Col.Add "ssss", "item5"
     
     For i = 1 To Col.Count
         Debug.Print ColKey(i, Col)
     Next
End Sub
Private Function ColKey(ByVal Index As Long, Col As Collection) As String
     Dim lpSTR As Long, Ptr As Long, Key As String
     If Col Is Nothing Then Exit Function
     Select Case Index
     Case Is < 1, Is > Col.Count: Exit Function
     Case Else
         Ptr = ObjPtr(Col)
         Do While Index
             GetMem4 ByVal Ptr + 24, Ptr
             Index = Index - 1
         Loop
     End Select
     GetMem4 ByVal VarPtr(Key), lpSTR
     GetMem4 ByVal Ptr + 16, ByVal VarPtr(Key)
     ColKey = Key
     GetMem4 lpSTR, ByVal VarPtr(Key)
End Function
Последний раз редактировалось The trick 22.04.2022 (Пт) 19:10, всего редактировалось 1 раз.
UA6527P

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

Re: Получить значения ключей коллекции

Сообщение Хакер » 11.03.2014 (Вт) 19:20

Это не кирпич. Переношу.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получить значения ключей коллекции

Сообщение ger_kar » 11.03.2014 (Вт) 20:29

Получается, что коллекция в VB это список (интересно какой, односвязный или двусвязный?) где по смещению 24 хранится адрес следующего элемента и у конкретного элемента по смещению 16 хранится указатель на строку ключа. А что еще известно о коллекции? Что хранится по другим адресам элемента?
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получить значения ключей коллекции

Сообщение The trick » 11.03.2014 (Вт) 21:01

Что мне известно -
Коллекция хранит данные в двусвязном списке, каждый элемент представляет собой пару значение-ключ, где значение представлено типом Variant. Внутри объекта коллекции по смещению 24 находится указатель на первый элемент списка, по смещению 28 на последний. Каждый элемент по смещению 24 содержит указатель на следующий элемент списка, по смещению 20 на предыдущий. Т.к. данные хранятся в виде пары значение(Variant)-ключ(String(BSTR)), то для того чтобы добраться до значения ключа, нужно прибавить 16 (размер типа Variant). Например если ты хочешь добраться до значения определенного элемента можешь сделать так:
Код: Выделить всё
Private Function ColItem(ByVal Index As Long, Col As Collection) As Variant
    Dim Ptr As Long, Key As Variant
    If Col Is Nothing Then Exit Function
    Select Case Index
    Case Is < 1, Is > Col.Count: Exit Function
    Case Else
        Ptr = ObjPtr(Col)
        Do While Index
            GetMem4 ByVal Ptr + 24, Ptr
            Index = Index - 1
        Loop
    End Select
    GetMem8 ByVal Ptr, ByVal VarPtr(Key)             ' Одну половину копируем
    GetMem8 ByVal Ptr + 8, ByVal VarPtr(Key) + 8     ' Вторую половину копируем
    ColItem = Key
End Function

Получение элемента коллекции по ключу
Код: Выделить всё
Private Function ColItem(Key As String, Col As Collection) As Variant
    Dim lpStr As Long, Ptr1 As Long, Ptr2 As Long, sKey As String

    GetMem4 ByVal ObjPtr(Col) + 36, Ptr1
    GetMem4 ByVal ObjPtr(Col) + 40, Ptr2

    Do Until Ptr1 = Ptr2
        GetMem4 ByVal Ptr1 + 16, lpStr
        Select Case VarBstrCmp(ByVal StrPtr(Key), ByVal lpStr, 1, &H30001)
        Case 0: GetMem4 ByVal Ptr1 + 40, Ptr1
        Case 1
            Ptr2 = VarPtr(ColItem)
            GetMem8 ByVal Ptr1, ByVal Ptr2
            GetMem8 ByVal Ptr1 + 8, ByVal Ptr2 + 8
            Exit Function
        Case Else: GetMem4 ByVal Ptr1 + 36, Ptr1
        End Select
    Loop
   
    MsgBox "Element not found"
End Function
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получить значения ключей коллекции

Сообщение ger_kar » 11.03.2014 (Вт) 21:10

Спасибо, было познавательно. А в самом элементе по смещению 28 тоже хранится указатель на последний элемент или элемент коллекции ограничен 24 байтами?
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получить значения ключей коллекции

Сообщение The trick » 11.03.2014 (Вт) 21:12

ger_kar писал(а):А в самом элементе по смещению 28 тоже хранится указатель на последний элемент или элемент коллекции ограничен 24 байтами?

Я уже не помню, надо в отладчик лезть и смотреть. Пока времени нет
UA6527P

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

Re: Получить значения ключей коллекции

Сообщение Хакер » 12.03.2014 (Ср) 0:41

ger_kar писал(а):Получается, что коллекция в VB это список (интересно какой, односвязный или двусвязный?) где по смещению 24 хранится адрес следующего элемента и у конкретного элемента по смещению 16 хранится указатель на строку ключа. А что еще известно о коллекции? Что хранится по другим адресам элемента?


Это очень плохой способ. Это в одной версии рантайма он по смещению 24. А в другой версии он может оказаться по смещению 20 или 28.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получить значения ключей коллекции

Сообщение ger_kar » 12.03.2014 (Ср) 5:17

Хакер писал(а):Это очень плохой способ. Это в одной версии рантайма он по смещению 24. А в другой версии он может оказаться по смещению 20 или 28.
Ну в принципе можно проверить все известные версии рантаймов на текущий момент или как вариант в папку с приложением класть известную и проверенную версию рантайма, тем более что если этот метод и потребуется когда нибудь, то будет это достаточно редко. Я так думаю.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получить значения ключей коллекции

Сообщение The trick » 12.03.2014 (Ср) 6:15

Это очень плохой способ. Это в одной версии рантайма он по смещению 24. А в другой версии он может оказаться по смещению 20 или 28.

Ни разу не встречался рантайм где элементы коллекции отличались бы от того что я описал.
UA6527P

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

Сообщение Qwertiy » 13.03.2014 (Чт) 11:50

Хакер писал(а):Это очень плохой способ. Это в одной версии рантайма он по смещению 24. А в другой версии он может оказаться по смещению 20 или 28.

Только вот рантайм-то уже не поменяется... Если в старых так, то будет оно работать и никуда не денется. По крайней мере, если ты вдруг 64-битный рантайм не сделаешь ;)

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

Re: Получить значения ключей коллекции

Сообщение Хакер » 13.03.2014 (Чт) 11:53

Qwertiy писал(а):Только вот рантайм-то уже не поменяется... Если в старых так, то будет оно работать и никуда не денется. По крайней мере, если ты вдруг 64-битный рантайм не сделаешь ;)

MS выпускает новые рантаймы. Интерфейс рантайма не поменяется, а вот внутренности — поменяются.

Я могу совершенно точно заявить, что я проанализировал много версий рантаймов (в рамках работы по реверс-инженерингу внутренних структур) и замечал много изменений в наборе полей структур от версии к версии.

Так что предложенный способ очень грязный и и не может считаться достойным применения.
—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 » 13.03.2014 (Чт) 11:56

Хакер писал(а):MS выпускает новые рантаймы. Интерфейс рантайма не поменяется, а вот внутренности — поменяются.

Как часто? И когда вышел последний?

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

Re: Получить значения ключей коллекции

Сообщение Хакер » 13.03.2014 (Чт) 12:19

Qwertiy писал(а):Как часто? И когда вышел последний?

Очевидно, что частота выпуска убывает по гиперболе, снижаясь от «раз в месяц» до «раз в три года», потому что старые критические баги правятся, а новых не появляется.

Хочешь экстраполировать?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получить значения ключей коллекции

Сообщение ger_kar » 13.03.2014 (Чт) 16:40

Хакер писал(а):старые критические баги правятся, а новых не появляется.
Ну вот коллекции багами вроде не страдают, поэтому вряд ли в них будут вносится изменения. Гарантии конечно 100% нет, но и вероятность того что что-то изменится в механизме коллекции чрезвычайно мала.
Qwertiy писал(а):И когда вышел последний?

Версия: 6.0.98.15
Размер файла: 1386496 байт
Последнее обновление: 6/10/2009
Это последняя известная мне версия. В Windows 8 какая версия не в курсе, может и более новая.
Бороться и искать, найти и перепрятать


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

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

Сейчас этот форум просматривают: Google-бот и гости: 46

    TopList  
cron