В моем приложении я подключаю различные функции для создания COM-объектов (таких как CoCreateInstanceEx
), чтобы получать уведомления, когда какой-либо объект создано. Я отслеживаю все созданные объекты в std::list
, и я повторяю этот список, чтобы делать разные вещи (например, проверить, какой OLE объекты были активированы).
Проблема с этим заключается в том, что прямо сейчас, добавляя указатель IUnknown
к моему списку, я вызываю IUnknown::AddRef
, чтобы убедиться, что он не будет уничтожен, пока я его отслеживаю. Это не то, что я действительно хочу; время жизни объекта должно быть таким же длинным (или коротким), как и без моего кода трассировки, поэтому я бы предпочел сохранить слабую ссылку на объектах. Всякий раз, когда последняя ссылка на какой-то отслеживаемый COM-объект удаляется (и, следовательно, объект уничтожается), я хотел бы получить уведомление, чтобы я мог обновить мою учетную запись (например, установив указатель в моем списке на NULL
). *
Какой лучший способ сделать это? Прямо сейчас я исправляю (первый) VTable всех созданных объектов, чтобы уведомления о IUnknown::Release
через первый vtable получили уведомление. Однако это не будет работать для интерфейсов COM, которые наследуют от нескольких интерфейсов (и, следовательно, имеют несколько vtables), но я не уверен, действительно ли это проблема: с учетом Правила реализации QueryInterface, всегда должен быть только один IUnknown
, возвращенный IUnknown::QueryInterface
, правильно? Поэтому я мог бы это сделать, а затем исправить эту таблицу vtable.
Кроме того, этот подход также немного волосатый, поскольку он включает создание thunks, которые генерируют некоторый код. Я только реализовал это для 32 бит до сих пор. Не большая проблема, но все же.
Мне действительно интересно, нет ли более элегантного способа иметь слабую ссылку на COM-объект. Кто-нибудь знает?
*: Следующее, что мне нужно решить, - это правильно выполнить эту работу, если у меня есть активные итераторы (я использую пользовательские объекты итератора), проходящие по списку объектов COM. Мне может потребоваться отслеживать активные итераторы, и как только последний закончен, удалите все нулевые указатели из списка. Или что-то в этом роде.