В соответствии со спецификацией: ActiveX — это поставщик классов (и их фабрик), контейнер их кода, регистратор их данных в реестре и счётчик их количества. И
ничто больше. Именно по этой причине, а не из вредности, MS не сделали в VB экспорт обычных функций (
а я сделал).
Поскольку ActiveX-сервер это только поставщик классов, будучи inproc-сервером и работая как модуль (в виндовом смысле слова) внутри процесса-хоста (клиента), нет никакой причины модулю быть загруженным в процесс, если в текущий момент не существует ни одного экземпляра объекта его класса.
Поэтому, любой inproc-сервер ведёт подсчёт своих объектов для того, чтобы быть способным в любой момент сказать:
- Есть объекты, которые я создал и за которые отвечаю, поэтому меня нельзя выгружать.
- Сейчас нет объектов, которые бы я создал, поэтому меня можно спокойно выгрузить, я никому сейчас не нужен.
Отвечает на этот вопрос функция DllCanUnloadNow, которую любой inproc-сервер должен экспортировать.
Таким образом, если сервер не породил ни одного объекта (которые бы до сих пор были живыми), он может быть выгружен в любой момент (предугадать невозможно). Причём выгружает его COM, а не сам сервер выгружает себя; сам сервер только докладывает, можно ли его выгрузить.
Если говорить об обычных (неVB) модулях (в виндовом смысле этого слова), то там «смерть» глобальных и статических переменных происходит при выгрузке модуля из АП процесса.
Если перенести это на не просто модули, а на ActiveX-библиотеки, выполненные как модули, получается
неопределённость.
Если все объекты умерли, глобальная переменная может:
- как дожить до момента рождения следующего объекта, если модулю повезёт остаться не выгруженным
- так и не дожить до него, если COM внезапно решит выгрузить модуль до наступления этого момента (и загрузит обратно при его наступлении).
Получается плохая ситуация (любая неопределённость в программировании — очень плохая ситуация): программист не может полагаться на глобальные и статические переменные, потому что они могут как обнулиться, так и не обнулиться (в зависимости от текущей ситуацией с памятью и инициативой COM выгружать ненужные модули).
Поэтому неопределённое поведение устранили, внеся в это дело определённость: вне зависимости от того, будет ли выгружен из памяти неиспользуемый модуль или не будет, как только модуль становится неиспользуемым, то есть, как только счётчик порождённых объектов достигаетя значения ноль, VB насильно зануляет все глобальные и статические переменные.
С учётом этого, нет разницы, будет ли между смертью последнего объекта и рождением нового первого произведена выгрузка (с повторной загрузкой при рождении) модуля, или же не будет — в любом случае при смерти последнего объекта гл./стат. переменные зануляются, и к моменту создания нового будут гарантировано обнулены.
Собственно, ответ и на вопрос и само определённое поведение таково: время жизни глобальных и статических переменных в ActiveX-бибилиотеках соответствует
объединению (мат. опер.) времён жизни всех объектов, принадлежащих этой библиотеки, и заканчивается смертью последнего из них.