当您在运行对象表中使用零标志(请求弱参考)注册COM对象时,ROT将引用计数递增1.从ROT获取对象的行为将引用计数增加一个。一旦释放了该对象,该对象将保持活动状态,其引用次数至少为1。它在ROT中的注册也不会在检索时被神奇地撤销。
这有多弱?这与强势注册有何不同?
强注册遵循相同的模式 - 注册和检索都将引用计数递增1。
ROT返回公寓客户端的接口指针不是代理; ROT无法知道我已经释放了我检索到的接口指针。
答案 0 :(得分:2)
真正从ROT行为中删除,不仅取决于ROTFLAGS_REGISTRATIONKEEPSALIVE
标志,还取决于您的对象实现(以及如何)IExternalConnection
(仅限@IInspectable的特别说明 - 是的,所有这些都是未记录的,不受支持的,可以更改 - 所以请不要阅读更多)。
当我们在ROT中注册对象时,总是向他查询IExternalConnection
接口。如果对象没有实现它 - 使用默认实现。
以防 ROTFLAGS_REGISTRATIONKEEPSALIVE
已在注册时IExternalConnection::AddConnection
调用。所以我们已经有1个外部连接。没有ROTFLAGS_REGISTRATIONKEEPSALIVE
- 此方法未被调用。
每当有人在我们的流程中调用IRunningObjectTable::GetObject
(!来自其他公寓)时调用CRemoteUnknown::RemAddRef
。此方法仅在我们注册而不是 ROTFLAGS_REGISTRATIONKEEPSALIVE
标记时调用IExternalConnection::AddConnection
。
每次我们最终Release
对象(!on proxy,from previous GetObject
call ) - CRemoteUnknown::RemReleaseWorker
在我们的本地进程中调用。如果对象上的否 ROTFLAGS_REGISTRATIONKEEPSALIVE
,它会在内部调用IExternalConnection::ReleaseConnection
。名为CStdMarshal::Disconnect
的{{3}}的默认实施 - > InternalIrotRevoke
当外部引用(不是tottal对象引用)达到0和fLastReleaseCloses == TRUE
时 - 结果我们的对象从ROT中撤销。但如果我们自己实施IExternalConnection
,我们可以致电或不致电IExternalConnection
,以便我们可以撤销或不撤销ROT。
最后当我们直接或间接致电CoDisconnectObject
com来电话IRunningObjectTable::Revoke
如果我们将注册 ROTFLAGS_REGISTRATIONKEEPSALIVE
。
结论:
如果我们注册ROTFLAGS_REGISTRATIONKEEPSALIVE
- IExternalConnection::ReleaseConnection
,则只会在注册时调用一次(实际上可以称为n+1
时间和n
时间 - {{1} } - 但所有这些都在IExternalConnection::AddConnection
内部调用。)。当有人从ROT获取我们的对象时 - 我们将未通知。当我们拨打IRunningObjectTable::Register
时,最后IExternalConnection::ReleaseConnection
也会被调用。
另一方面,如果我们不使用ReleaseConnection
标记 - IRunningObjectTable::Revoke
方法,则ROTFLAGS_REGISTRATIONKEEPSALIVE
和Register
上的不会被称为。但在IExternalConnection
和最终Revoke
(在对象代理上)多次调用。如果我们没有自己实施IRunningObjectTable::GetObject
或在外部裁判达到0和Release
时致电IExternalConnection
,我们将从ROT中删除。但是我们可以免费不调用 CoDisconnectObject
(在这种情况下,行为就像我们使用fLastReleaseCloses
)或者说在某种情况下调用它。
优点 - 我们可以跟踪每个对象的使用情况,如果没有ROTFLAGS_REGISTRATIONKEEPSALIVE
标志,并且当外部参考值达到0时,自我决定是否需要断开连接。
和最后一个 - 如果我们从我们称之为CoDisconnectObject
的同一个公寓中调用IRunningObjectTable::GetObject
- 我们没有代理,而是直接对象指针。在这种情况下,当然不会调用IRunningObjectTable::Register
方法