Есть сервер . Он в себе содержит некий интерфейс и его реализацию, причем такую, что объект этой реализации создать нельзя (макросы DECLARE_NO_REGISTRY и удален OBJECT_ENTRY_AUTO). Этот сервер создает внутри себя объект этого класса (с помощью CComObject), далее вывешивает событие (через Connection Point), в котором передает указатель на этот самый интерфейс.
Есть клиент. Клиент делает #import либки того самого сервера (соответственно содается некий "ВашИнтерфейсPtr", использующий _com_ptr_t), далее идет подписка на событие с использованием IDispEventImpl. Соответственно, функция обработчик в качестве параметра принимает тот самый "ВашИнтерфейсPtr".
А теперь вот что происходит: при создании объекта делается QueryInterface, в итоге счетчик у объекта становится 1. Потом полученный интерфейс передается в Fire_ВашеСобытие, и там в ::VarianCopy делается AddRef(), как следствие счетчик становится равным двум. По приходу в функцию-обработчик события счетчик остается равным тем же самым двум. Внутри функции ничего, кроме считывания данных из проперти объекта не происходит.
А вот при выходе из функции-обработчика счетчик почему-то уменьшается на 1 (осталось 1). Потом при удалении variantarg'a в Fire_ВашеСобытие происходит Release(), счетчик становится 0, объекту хана.
Расследование, рассматривание CallStack'a и прочие шаманства показали, что _com_ptr_t при выходе из функции-обработчика разрушается, и в его деструкторе вызывается Release().
Но AddRef() в этом _com_ptr_t вызван не был, то есть указатель на интерфейс ему скормлен некорректно, как следствие мы теряем одну ссылку и теряем нужный объект.
Происходит ли такое странное поведение по моей вине, или же это очередной "прикол" от M$?..
Заранее спасибо за ответы