共用方式為


IUnknown 的運作方式

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

IUnknown中的方法可讓應用程式查詢元件上的介面,以及管理元件的參考計數。

參考計數

參考計數是內部變數,會在 AddRef 方法中遞增,並在 Release 方法中遞減。 基類會管理參考計數,並同步存取多個執行緒之間的參考計數。

介面查詢

查詢介面也很簡單。 呼叫端會傳遞兩個參數:介面識別碼 (IID) ,以及指標的位址。 如果元件支援要求的介面,它會設定介面的指標、遞增自己的參考計數,並傳回S_OK。 否則,它會將指標設定為 Null ,並傳回E_NOINTERFACE。 下列虛擬程式碼顯示 QueryInterface 方法的一般大綱。 下一節所述的元件匯總會介紹一些額外的複雜度。

if (IID == IID_IUnknown)
    set pointer to (IUnknown *)this
    AddRef
    return S_OK

else if (IID == IID_ISomeInterface)
    set pointer to (ISomeInterface *)this
    AddRef
    return S_OK

else if ... 

else
    set pointer to NULL
    return E_NOINTERFACE

一個元件的 QueryInterface 方法與另一個元件的 QueryInterface 方法唯一差異是每個元件測試的 IID 清單。 針對元件支援的每個介面,元件必須測試該介面的 IID。

匯總和委派

元件匯總對呼叫端而言必須是透明的。 因此,匯總必須公開單一 IUnknown 介面,並將匯總的元件延遲至外部元件的實作。 否則,呼叫端會在相同的匯總中看到兩個不同的 IUnknown 介面。 如果未匯總元件,它會使用自己的實作。

若要支援此行為,元件必須新增間接存取層級。 委派 IUnknown會將工作委派給適當的位置:如果有外部元件,或委派給元件的內部版本。 非委派 IUnknown會執行工作,如上一節所述。

委派版本是公用的,並保留 名稱 IUnknown。 非委派版本已重新命名 為 INonDelegatingUnknown。 此名稱不是 COM 規格的一部分,因為它不是公用介面。

當用戶端建立元件的實例時,它會呼叫 IClassFactory::CreateInstance 方法。 其中一個參數是匯總元件 IUnknown 介面的指標,如果未匯總新的實例,則為 Null 。 元件會使用此參數來儲存成員變數,指出要使用的 IUnknown 介面,如下列範例所示:

CMyComponent::CMyComponent(IUnknown *pOuterUnkown)
{
    if (pOuterUnknown == NULL)
        m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this;
    else
        m_pUnknown = pOuterUnknown;

    [ ... more constructor code ... ]
}

委派 IUnknown 中的每個方法都會呼叫其非委派對應專案,如下列範例所示:

HRESULT QueryInterface(REFIID iid, void **ppv) 
{
    return m_pUnknown->QueryInterface(iid, ppv);
}

委派的本質是委派方法在每個元件中看起來都一樣。 只有未傳遞的版本會變更。

如何實作 IUnknown