簡體   English   中英

運行對象表如何實現弱引用?

[英]How does Running Object Table implement weak references?

當您在運行對象表中用零標志注冊COM對象(請求弱引用)時,ROT將引用計數增加1。從ROT獲取對象的動作會使引用計數再增加一。 一旦釋放了該對象,該對象就保持活動狀態,且引用計數至少為1。 檢索后,它在ROT中的注冊也不會被魔術撤銷。

那怎么弱? 這與強勢注冊有何不同?

強注冊遵循相同的模式-注冊和檢索都將引用計數加1。

ROT返回給公寓內客戶端的接口指針不是代理。 ROT無法知道我已釋放檢索到的接口指針。

真正擺脫ROT行為不僅取決於ROTFLAGS_REGISTRATIONKEEPSALIVE標志,而且取決於對象實現IExternalConnection (以及如何實現)

僅針對@IInspectable的特殊說明-是的,所有這些都是未記錄的,不受支持的,可以更改-因此請不要繼續閱讀 )。

當我們在ROT com中注冊對象時,總是向他查詢IExternalConnection接口。 如果對象未實現,則使用默認實現。

萬一 ROTFLAGS_REGISTRATIONKEEPSALIVE已經在注冊時IExternalConnection::AddConnection調用。 因此我們已經有1個外部連接。 沒有ROTFLAGS_REGISTRATIONKEEPSALIVE不調用此方法。

每次有人調用IRunningObjectTable::GetObject!從另一個公寓 )時,在我們的過程中調用CRemoteUnknown::RemAddRef 僅當我們注冊時未帶 ROTFLAGS_REGISTRATIONKEEPSALIVE標志時,此方法才調用IExternalConnection::AddConnection

每次當我們最終Release對象( !on代理,從先前的GetObject調用獲得 )時-在本地過程中調用 CRemoteUnknown::RemReleaseWorker 並且在對象上沒有 ROTFLAGS_REGISTRATIONKEEPSALIVE情況下才內部調用IExternalConnection::ReleaseConnection ROTFLAGS_REGISTRATIONKEEPSALIVE 當外部參考(不是全部對象參考)達到0並且fLastReleaseCloses == TRUE時, IExternalConnection默認實現稱為CStdMarshal::Disconnect > InternalIrotRevoke結果我們的對象已從ROT撤消。 但是,如果我們自行實現IExternalConnection ,則可以調用或不調用CoDisconnectObject因此可以從ROT撤消或不撤消。

最后, 如果我們 ROTFLAGS_REGISTRATIONKEEPSALIVE注冊 直接或間接調用IRunningObjectTable::Revoke com調用IExternalConnection::ReleaseConnection ROTFLAGS_REGISTRATIONKEEPSALIVE

這樣的結論:

如果我們用注冊ROTFLAGS_REGISTRATIONKEEPSALIVE - IExternalConnection::AddConnection將在注冊時只調用一次(真可謂說n+1的時間和n時間- ReleaseConnection -但這里面所有IRunningObjectTable::Register 。調用)。 當有人從ROT獲取我們的對象時-我們將不會收到通知 最后,當我們調用IRunningObjectTable::Revoke時, IExternalConnection::ReleaseConnection IRunningObjectTable::Revoke也將僅被調用一次。

另一方面,如果我們不使用ROTFLAGS_REGISTRATIONKEEPSALIVE標志-將不會Register and Revoke調用 IExternalConnection方法。 但是將在IRunningObjectTable::GetObject和最終Release在對象代理 多次調用 如果我們自己沒有實現IExternalConnection或在外部引用達到0和fLastReleaseCloses時調用CoDisconnectObject我們將從ROT中刪除。 但是我們不會隨意調用 CoDisconnectObject (在這種情況下,行為就像我們使用ROTFLAGS_REGISTRATIONKEEPSALIVE ),或者說在某種情況下調用它。

優勢-如果沒有ROTFLAGS_REGISTRATIONKEEPSALIVE標志,我們可以跟蹤每個對象的使用情況,並自行決定是否在外部引用達到0時斷開連接。

最后一個-如果我們在調用IRunningObjectTable::Register同一單元中調用IRunningObjectTable::GetObject ,則不是代理,而是直接對象指針。 在這種情況下,當然不會調用IExternalConnection方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM