действительно удаление от поведения ROT зависит не только от ROTFLAGS_REGISTRATIONKEEPSALIVE
флага, но также (и как) ваш объект реализован IExternalConnection
(специального примечания для @IInspectable только - да все это без документов, без поддержки, может изменился - поэтому, пожалуйста, не читайте больше).
когда мы регистрируем объект в ROT com, всегда запрашиваем его для интерфейса IExternalConnection
. если объект не реализован, используется стандартная реализация.
в случаеROTFLAGS_REGISTRATIONKEEPSALIVE
уже во время регистрации IExternalConnection::AddConnection
. поэтому у нас уже есть 1 внешнее соединение. без ROTFLAGS_REGISTRATIONKEEPSALIVE
- этот метод не называется.
каждый раз, когда кто-то называют IRunningObjectTable::GetObject
(! От другой квартиры) в CRemoteUnknown::RemAddRef
называется в нашем процессе. этот метод позвоните по номеру IExternalConnection::AddConnection
только если зарегистрируйтесь безROTFLAGS_REGISTRATIONKEEPSALIVE
флаг.
каждый раз, когда мы окончательный Release
объект (по доверенности, полученной от предыдущего GetObject
вызова!) - CRemoteUnknown::RemReleaseWorker
называется в нашем местном процессе. и он внутренне звонит IExternalConnection::ReleaseConnection
только в случае noROTFLAGS_REGISTRATIONKEEPSALIVE
на объекте. стандартная реализация IExternalConnection
по номеру CStdMarshal::Disconnect
->InternalIrotRevoke
, когда внешняя ссылка (не общая ссылка объекта) достигает 0 и fLastReleaseCloses == TRUE
- в результате наш объект отменяется с ROT. но если мы выполним IExternalConnection
самостоятельно, мы можем позвонить или не позвонить CoDisconnectObject
, чтобы мы могли быть отозваны или нет из ROT.
и, наконец, когда мы прямо или косвенно вызов IRunningObjectTable::Revoke
ком вызов IExternalConnection::ReleaseConnection
если мы регистрируем сROTFLAGS_REGISTRATIONKEEPSALIVE
.
так вывод:
если мы фиксируем с ROTFLAGS_REGISTRATIONKEEPSALIVE
- IExternalConnection::AddConnection
будет вызываться только один раз во время регистрации (. На самом деле можно назвать сказать n+1
время и n
время - ReleaseConnection
- но все это внутри IRunningObjectTable::Register
вызова) , когда кто-то получит наш объект от ROT - мы будем не уведомлены об этом. и, наконец, IExternalConnection::ReleaseConnection
будет называться также только один раз, когда мы позвоним IRunningObjectTable::Revoke
.
с другой стороны, если мы не используем ROTFLAGS_REGISTRATIONKEEPSALIVE
флаг - IExternalConnection
методы будут не называется на Register
и Revoke
. но это будет несколько раз по имени на IRunningObjectTable::GetObject
и окончательный Release
(на объекте прокси). если мы не реализовали IExternalConnection
самостоятельно или позвонили по номеру CoDisconnectObject
, когда внешние ссылки достигли 0 и fLastReleaseCloses
- мы будем удалены из ROT. но мы освобождаем не звонимCoDisconnectObject
(в этом случае поведение будет таким, как мы используем ROTFLAGS_REGISTRATIONKEEPSALIVE
) или произнесите его при некотором условии.
Преимущество - мы можем отслеживать использование каждого нашего объекта в случае, если флажок и ROTFLAGS_REGISTRATIONKEEPSALIVE
флаг и решить сами по себе, необходимо отключить, если внешние ссылки достигнут 0 или нет.
и последний - если мы позвоним IRunningObjectTable::GetObject
из той же квартиры, где мы позвоним IRunningObjectTable::Register
- мы получили не прокси, а указатель прямого объекта. в этом случае, конечно, не будет вызовов IExternalConnection
методов
Из [IRunningObjectTable :: Register] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms680747.aspx): * " Для слабой регистрации (ROTFLAGS_REGISTRATIONKEEPSALIVE не установлен) ROT будет освобождать объект всякий раз, когда выдается последняя сильная ссылка на объект. Для сильной регистрации (набор ROTFLAGS_REGISTRATIONKEEPSALIVE) ROT предотвращает уничтожение объекта до тех пор, пока регистрация объекта не будет явно отозван. "* – IInspectable
Я читал это. Не могли бы вы объяснить, что означает «последняя сильная ссылка на объект, выпущенный»? Если вы просто получите его из ROT и затем отпустите, он не освободит объект. В слабом сценарии ROT содержит ссылку, как в сильной. –
То, как я это понимаю (и я должен признать, что я никогда не делал дополнительной проверки), заключается в том, что запрос сильной регистрации «ROTFLAGS_REGISTRATIONKEEPSALIVE» гарантирует, что ROT имеет действительную ссылку независимо от того, что. Без флага он запускается аналогичным образом (просто нет другого способа, например, эта документация утверждает, что начальный «AddRef» всегда происходит), но API оставляет за собой право выпускать запись в любое время, особенно. на конкретном событии, таком как выпуск прокси. –