在运行对象表中注册COM对象时,如果使用零标志(请求弱引用),则ROT会使引用数增加1。从ROT获取对象的行为会使ref计数再增加一次。一旦释放了该对象,则该对象将保持活动状态,其参考数至少为1。它在ROT中的注册也不会在检索时神奇地被撤销。
,那怎么会弱呢?这和强注册有什么不同?
强注册遵循相同的模式-注册和检索都会使引用数增加1。
ROT返回给公寓内客户端的接口指针不是代理;ROT无法知道我已经释放了检索到的接口指针。
发布于 2016-11-20 05:23:09
实际上,从ROT行为中移除不仅依赖于ROTFLAGS_REGISTRATIONKEEPSALIVE
标志,而且还取决于对象实现IExternalConnection
的方式。
(特别注意@IInspectable是的,所有这些都是没有文件的,没有支持,可以更改-所以请不要阅读更多)。
当我们在ROT中注册对象时,总是询问他是否有IExternalConnection
接口。如果对象未实现,则使用默认实现。
,以防万一, ROTFLAGS_REGISTRATIONKEEPSALIVE
已经在注册时IExternalConnection::AddConnection
调用了。所以我们已经有了一个外部连接。没有ROTFLAGS_REGISTRATIONKEEPSALIVE
-此方法不调用。
每次有人打电话给IRunningObjectTable::GetObject
(!(从另一个公寓) CRemoteUnknown::RemAddRef
在我们的进程中调用。此方法只在IExternalConnection::AddConnection
注册而没有 ROTFLAGS_REGISTRATIONKEEPSALIVE
标志的情况下调用ROTFLAGS_REGISTRATIONKEEPSALIVE
。
每次我们最终确定Release
对象时(!on proxy,从以前的GetObject
调用中获得)-在本地进程中调用CRemoteUnknown::RemReleaseWorker
。它在内部调用IExternalConnection::ReleaseConnection
only,以防对象上的没有 ROTFLAGS_REGISTRATIONKEEPSALIVE
。IExternalConnection
的默认实现称为CStdMarshal::Disconnect
-> InternalIrotRevoke
,当外部引用(而不是总体对象引用)达到0和fLastReleaseCloses == TRUE
时--因此我们的对象被从ROT中撤销。但是,如果我们通过自我实现IExternalConnection
,我们可以调用或不调用CoDisconnectObject
,这样我们就可以从ROT中被撤销或不被撤销。
最后,当我们直接或间接调用IRunningObjectTable::Revoke
com调用IExternalConnection::ReleaseConnection
if时,我们向 ROTFLAGS_REGISTRATIONKEEPSALIVE
注册。
so结论:
如果我们在ROTFLAGS_REGISTRATIONKEEPSALIVE
注册-- IExternalConnection::AddConnection
将只在注册时被调用一次(实际上可以称为n+1
time和n
time - ReleaseConnection
),但这一切都在IRunningObjectTable::Register
中。当有人从ROT中得到我们的对象时--我们将不会被通知这件事。最后,当我们调用IExternalConnection::ReleaseConnection
时,也只能调用IRunningObjectTable::Revoke
一次。
另一方面,如果我们不使用ROTFLAGS_REGISTRATIONKEEPSALIVE
标志- IExternalConnection
方法将是,而不是在Register
和Revoke
上调用。但这将是多次调用 on IRunningObjectTable::GetObject
和最终Release
(在对象代理上)。如果我们没有自己实现IExternalConnection
,或者当外部引用达到0和fLastReleaseCloses
时调用CoDisconnectObject
,那么我们将被从ROT中删除。但是我们释放了,而不是调用 CoDisconnectObject
(在这种情况下,行为将类似于我们使用ROTFLAGS_REGISTRATIONKEEPSALIVE
),或者说在某些条件下调用它。
优势-我们可以跟踪每一个我们的对象使用的情况下,如果没有ROTFLAGS_REGISTRATIONKEEPSALIVE
标志,并决定由自己是需要断开时,外部参考达到0或不。
最后一个--如果我们从我们调用IRunningObjectTable::Register
的同一间公寓调用IRunningObjectTable::Register
--我们得到的不是代理,而是直接的对象指针。在这种情况下,当然不会调用IExternalConnection
方法
https://stackoverflow.com/questions/40695654
复制