Эта функция для DllCanUnloadNow()
для правильной работы.
Вы знаете, что когда вы вызываете CoCreateInstance()
для внутрипроцессного сервера, COM автоматически вызывает LoadLibraryEx()
для загрузки DLL COM-сервера при необходимости. Но как долго DLL хранится в загруженном состоянии? Фактически COM периодически вызывает DllCanUnloadNow()
для каждой загруженной DLL-библиотеки COM-сервера. Если возвращается S_OK
COM разрешено звонить FreeLibrary()
.
Когда безопасно выгружать DLL? Очевидно, вы не сможете выгрузить его, пока все объекты, реализованные в DLL, не будут уничтожены. Итак, вот вам и «счетчик блокировок» - глобальная целочисленная переменная, подсчитывающая количество живых объектов, реализованных DLL.
Когда создается новый COM-объект - CComModule::Lock()
вызывается из его конструктора (обычно CComObject
конструктор) и увеличивает значение переменной, когда объект уничтожается - CComModule::Unlock()
вызывается из его деструктор и уменьшает переменную. Когда CComModule::GetLockCount()
возвращает ноль, это означает, что живых объектов нет и выгрузить DLL безопасно.
Таким образом, счетчик блокировок очень похож на счетчик ссылок, реализованный IUnknown
. Число ссылок для каждого объекта, число блокировок для каждого внутрипроцессного сервера COM.