Я следую примеру Microsoft, приведенному для «Как создать интерфейс приемника в COM-клиенте на основе MFC» , чтобы создать приемник событий в C ++ (VC6).Источником события является сборка .NET, которая демонстрирует свою функциональность через взаимодействие COM.
Подходит мне то, что мне нужно, это последняя заметка образца:
Поскольку CMySink былсозданный в куче, убедитесь, что вы удалили его, чтобы избежать утечек памяти.
Несколько вещей, которые я отмечаю:
- Параметр автоинкремента / декрементаДля GetIDispatch и AfxConnectAdvise / AfxConnectUnadvise установлено значение FALSE, поэтому я предполагаю, что внутренний счетчик ссылок для приемника остается неизменным на протяжении всего упражнения.
- Метод OnFinalRelease не показан в упражнении, поэтому я предполагаю, что онэто стандартное поведение удаления экземпляра приемника.
Учитывая, что последнее примечание в тексте примера, мой код очистки выглядит примерно так:
//Get a pointer to sinks IUnknown, no AddRef.
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE);
//Terminate a connection between source and sink.
//m_pUnkSrc is IUnknown of server obtained by CoCreateInstance().
//m_dwCookie is a value obtained through AfxConnectionAdvise().
AfxConnectionUnadvise(m_pUnkSrc, IID_MYEVENT, pUnkSink, FALSE,
m_dwCookie);
delete m_pUnkSink;
Код, который является частью этого примера, запускается в цикле, который включает в себя создание приемника, его подключение, ожидание нескольких событий, затем срывание и удаление.Я вижу, что после нескольких раундов цикла OnFinalRelease вызывается неожиданно.Мало того, OnFinalRelease вызывается для экземпляра приемника для текущей итерации цикла (а не для какого-либо предыдущего экземпляра, использованного предыдущей итерацией цикла).В результате текущий приемник удаляется из-под выполнения текущего цикла, и в результате возникает куча ошибок нулевого указателя.
Я попытался удалить вызов delete m_pUnkSink.В результате OnFinalRelease никогда не вызывается.Это оставляет меня с утечкой памяти, так как все эти экземпляры приемника накапливаются в куче.
Я думаю, что я мог бы избежать повторного использования одного и того же экземпляра приемника для каждой итерации цикла, ноМне любопытно, что такое правильное управление временем жизни.Нужно ли делать явный выбор между удалением экземпляра самостоятельно и переопределением OnFinalRelease, чтобы ничего не делать, вместо того, чтобы никогда не удалять себя и всегда ожидать, что OnFinalRelease выполнит удаление?Один предпочитает другому?