Почему моя фабрика COM никогда не выпускается при жизни программы? - PullRequest
3 голосов
/ 27 октября 2010

У меня есть встроенный COM-сервер C ++ ATL. Отдельная программа испытаний

  • звонки CoInitialize(),
  • звонки CoCreateInstance(), затем
  • звонит Release() по указателю,
  • затем вызывает CoUnitialize() и выходит.

Если я запускаю тестовую программу в отладчике Visual C ++, CRT отладки сообщает об одной утечке памяти, и каждый раз номер выделения совпадает.

Я использовал хук выделения и обнаружил, что объект, не возвращаемый в кучу, является объектом фабрики классов.

Итак, в основном происходит следующее:

  • программа вызывает CoCreateInstance()
  • COM внутренние звонки DllGetClassObject()
  • ATL создает экземпляр фабрики и передает право собственности вызывающей стороне (внутренним компонентам COM)

и затем фабрика никогда не освобождается - я не вижу достаточно вызовов Release() фабрики классов.

Что происходит? Это дефект во время выполнения COM?

1 Ответ

2 голосов
/ 01 ноября 2010

Оказывается, это проблема реализации ATL.

Сервер использует глобальный экземпляр класса CComModule.Когда вызывается CComModule::DllClassObject(), он создает экземпляр фабрики классов и кэширует его на карте, на которую ссылается объект CComModule.Так что на самом деле CComModule объект владеет фабрикой классов.Когда деструктор CComModule запускается, он не освобождает фабрики кэшированных классов.

Чтобы освободить все фабрики кэшированных классов, необходимо вызвать метод CComModule::Term() до того, как сервер выгружен.IMO, самый чистый способ достичь этого - извлечь из CComModule и вызвать CComModule::Term() в деструкторе производного класса.

...