Как VBA определяет время жизни неизвестных ссылочных типов? - PullRequest
4 голосов
/ 06 февраля 2020

Я пытаюсь понять, что диктует время жизни разных битов данных; откуда интерпретатор VBA знает, что безопасно освободить связанную память для данной переменной. Вот что я нашел до сих пор:

Типы значений

Простые типы значений используют область для определения времени жизни; например, Long, то есть Dim med внутри функции, будет зависать до тех пор, пока не будет нажата инструкция Exit/End *. На данный момент точный механизм неясен для меня, но я представляю, что интерпретатор VBA хранит список всех переменных в данной области и использует VarPtr и LenB для освобождения всей памяти, связанной с ними.

Типы объектов

Между тем все объекты являются производными от интерфейса IDispatch, который основан на интерфейсе COM IUnknown. В результате объекты используют подсчет ссылок для определения времени жизни. Таким образом, переменная, которая содержит ссылку на объект (в основном LongPtr), будет перезаписана, когда она выйдет из области видимости (аналогично типам значений), но непосредственно перед этим интерпретатор VBA вызывает IUnknown_Release для IUnknown интерфейс объекта (или, точнее, любой интерфейс, содержащийся в блоке переменных / With).

Таким образом, COM-объект несет ответственность за очистку и освобождение собственной памяти экземпляра всякий раз, когда счетчик ссылок падает до нуля

Другие типы ссылок

Есть другие ссылочные типы (то есть, типы, которые не хранятся в виде необработанных данных, таких как Doubles и Longs, но вместо этого как указатели на полные данные в другом месте). Например:

  • Строки
  • Массивы
  • UDT
  • Все, что передано ByRef

Теперь, поскольку они не являются строго типы значений, VBA не может просто использовать область для определения времени жизни; давайте предположим, что некоторая функция Dim s является массивом, который выходит из области видимости, когда функция End s. Хорошо, если по умолчанию VBA вызывает SafeArrayDestroy для указателя массива, память освобождается, как только переменная выходит из области видимости. Однако что произойдет, если массив является возвращаемым значением функции - теперь VBA не может освободить базовые данные, когда переменная выходит за пределы области видимости или что-то сломается. Если массив не использует подсчет ссылок, то как VBA узнает, чтобы освободить его или нет?

Аналогично для других типов - любая подсказка, которая точно определяет время жизни этих половинных половинных ссылочных типов (все они назначается без оператора Set, так что я думаю, что они не являются строго ссылочными типами)

...