2011-03-04 28 views
1

我發現一個out-proc COM服務器以這種方式實現(假設是由於一個bug),如果客戶端調用CoGetClassObject(),然後永遠不會嘗試用檢索到的工廠實例化任何東西,服務器進程將永遠運行。 COM服務器不作爲服務啓動,它是一個純粹的可執行文件。如果一個out-proc COM服務器最終會在所有情況下停止使用它,

在描述的情況下,客戶端永遠不會調用IClassFactory::LockServer(),所以這個問題是完全忽略這些「服務器鎖」。

這是正確的行爲嗎?在一段時間內沒有爲服務對象提供服務的情況下,還是應該在某些情況下,即使服務器不提供任何對象,也應該連續運行COM服務器?

回答

3

Out of process servers and IClassFactory::LockServer()

COM增加了一個隱式調用與TRUE以LockServer對類對象時,它的編組的IClassFactory接口和一個隱含的呼叫與FALSE到LockServer當客戶端釋放的IClassFactory接口。因此,不需要將LockServer調用遠程返回給服務器,並且LockServer的代理僅僅返回S_OK而不實際遠程調用該調用。

該進程應該運行,直到類對象被釋放爲(原始)COM不提供任何類型的超時機制。所以是的,直到你 - >釋放()類對象的接口,你用CoGetClassObject()獲得,服務器進程(託管的DLL或EXE)將繼續運行。該行爲與由類對象(工廠)創建的類無關,因爲這些類是分別引用的。

FWIW,檢索到的接口也不一定是IClassFactory。它可以是某種自定義實現,所以您可以在COM提供的衆所周知的接口之外進行操作。我覺得奇怪的是CoGetClassObject被調用而不是CoCreateInstance(Ex),因爲調用CoGetClassObject()實際上是一個用於創建多個對象的特殊用途的工具。我從來沒有發現自己使用類對象,或者monikers,或者COM支持的其他一些行爲。 DCOM,COM +,OLE,當然,但不是低級的原始東西。

1

我認爲該計劃是正確的。 CoGetClassObject返回一個AddRef'ed接口,如果這不是Release'd,EXE不應該退出。

+0

工廠在out-proc服務器中的處理方式不同,因爲CoRegisterClassObject()也是AddRef()的工廠接口,所以如果服務器等待工廠被釋放它永遠不會停止。這就是爲什麼out-proc服務器中的「鎖計數」只包含非工廠對象的原因。 – sharptooth

+1

當客戶端釋放IClassFactory接口時,COM對類對象封裝IClassFactory接口並向FALSE隱式調用Lock時,COM向LockServer添加一個隱式調用。因此,不需要將LockServer調用遠程返回給服務器,並且LockServer的代理僅僅返回S_OK而不實際遠程調用該調用。 –

+0

http://msdn.microsoft.com/en-us/library/ms679709(v=vs.85).aspx –

相關問題