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