Как работать с GetMemObj

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
nouyana
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 114
Зарегистрирован: 29.01.2016 (Пт) 17:42

Как работать с GetMemObj

Сообщение nouyana » 10.05.2024 (Пт) 20:39

Отчасти этот вопрос является продолжением этой темы, но я решил создать новую, так как теперь вопрос гораздо более узкий и уже не теоретический, а для дела понадобилось.

Итак, начну с задачи, которую я решаю - может, кто подскажет другой способ. У меня есть класс Database, представляющий базу данных SQLite. Есть также класс Recordset, представляющий наборы записей. Я создаю множество экземпляров класса Recordset, родителем которых является объект Database.

В какойто момент объект Database запускает на выполнение какую-нибудь инструкцию SQL, и мне необходимо пробежаться по всем дочерним объектам Recordset, чтобы выполнить их метод Refresh. Вот такая, тривиальная на первый взгляд, задача.

Первое, что пришло на ум: создать коллекцию объектов Recordset внутри класса Database и добавлять туда все вновь созданные объекты, чтобы при необходимости можно было их перебрать. Проблема: объекты Recordset иногда удаляются из памяти (Set rs = Nothing), и делается это НЕ внутри класса Database. А наличие коллекции объектов не позволяет очистить память (объекты Recordset могут занимать очень много памяти).

Таким образом, задача звучит так: нужно иметь возможность пробежаться только по существующим объектам Recordset, не мешая при этом очищать память. Следующей идеей было отказаться от коллекций и собирать массив ссылок VarPtr на все созданные объекты Recordset, что, как мне кажется не должно мешать очистке памяти (верно?). А в нужный момент я планировал воспользоваться функцией GetMemObj, чтобы при необходимости получать объектные переменные. Подразумевалось, что, если GetMemObj вернёт ошибку, значит ссылка на объект битая, и её можно удалить. Собственно, проблема оказалась именно в использовании GetMemObj:

Код: Выделить всё
Private Declare Function GetMemObj Lib "msvbvm60" _
   (ByVal pSrc As Long, ByRef MyObj As Object) As Long

Public Sub RefreshAllRecordsets()
     On Error GoTo ErrHandler
10   Dim i   As Long
12   Dim rv  As Long
14   Dim obj As Object
   
16   If Connection.AffectedRows = 0 Then Exit Sub
   
18   For i = 1 To nPointers
20      If aPointers(i) > 0 Then
22         rv = GetMemObj(aPointers(i), obj)
23         Debug.Print TypeName(obj)
24         If rv = 0 Then
26            obj.Refresh
28         Else
30            aPointers(i) = 0
32         End If
34      End If
36   Next
ErrHandler:
     Debug.Print Erl & ", " & Err.Description
End Sub


Не могу получить объектную переменную при помощи GetMemObj. Ошибки возникают в 22-ой строке и при помощи On Error внутри этой процедуры они не отлавливаются (вылетает в вызывающую процедуру в обычном модуле, минуя дочерний объект, который её реально вызвал). Строку определил при помощи установки Break point.

nouyana
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 114
Зарегистрирован: 29.01.2016 (Пт) 17:42

Re: Как работать с GetMemObj

Сообщение nouyana » 11.05.2024 (Сб) 9:11

nouyana писал(а):В какой-то момент объект Database запускает на выполнение какую-нибудь инструкцию SQL, и мне необходимо пробежаться по всем дочерним объектам Recordset, чтобы выполнить их метод Refresh.


Это ж надо было столько текста написать, чтобы самому себе объяснить, как решить задачу:) Проблема решена при помощи Raise Event в классе Database . Очень редко создаю классы, потому и не сообразил сразу. Однако, теоретические вопросы по корректному использованию GetMemObj остались. Может, Хакер ответит здесь или в этой теме.


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

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

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

    TopList