Matrice di modelli factory

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Il modello di factory contiene le variabili del membro pubblico seguenti:

const WCHAR *              m_Name;                // Name
const CLSID *              m_ClsID;               // CLSID
LPFNNewCOMObject           m_lpfnNew;             // Function to create an instance
                                                  //   of the component
LPFNInitRoutine            m_lpfnInit;            // Initialization function (optional)
const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; // Set-up information (for filters)

I due puntatori di funzione , m_lpfnNew e m_lpfnInit, usano le definizioni di tipo seguenti:

typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);

La prima è la funzione di creazione di istanze per il componente. Il secondo è una funzione di inizializzazione facoltativa. Se si specifica una funzione di inizializzazione, viene chiamata dall'interno della funzione di ingresso della DLL. La funzione punto di ingresso della DLL viene illustrata più avanti in questo articolo.

Si supponga di creare una DLL contenente un componente denominato CMyComponent, che eredita da CUnknown. È necessario specificare gli elementi seguenti nella DLL:

  • La funzione di inizializzazione, un metodo pubblico che restituisce una nuova istanza di CMyComponent.
  • Matrice globale di modelli di factory, denominata g_Templates. Questa matrice contiene il modello factory per CMyComponent.
  • Variabile globale denominata g_cTemplates che specifica le dimensioni della matrice.

Nell'esempio seguente viene illustrato come dichiarare questi elementi:

// Public method that returns a new instance. 
CUnknown * WINAPI CMyComponent::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
{
    CMyComponent *pNewObject = new CMyComponent(NAME("My Component"), pUnk, pHr );
    if (pNewObject == NULL) {
        *pHr = E_OUTOFMEMORY;
    }
    return pNewObject;
} 

CFactoryTemplate g_Templates[1] = 
{
    { 
      L"My Component",                // Name
      &CLSID_MyComponent,             // CLSID
      CMyComponent::CreateInstance,   // Method to create an instance of MyComponent
      NULL,                           // Initialization function
      NULL                            // Set-up information (for filters)
    }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);    

Il CreateInstance metodo chiama il costruttore della classe e restituisce un puntatore alla nuova istanza della classe. Il parametro pUnk è un puntatore all'aggregazione di IUnknown. È sufficiente passare questo parametro al costruttore della classe. Il parametro pHr è un puntatore a un valore HRESULT. Il costruttore della classe imposta questo valore su un valore appropriato, ma se il costruttore ha esito negativo, impostare il valore su E_OUTOFMEMORY.

La macro NAME genera una stringa nelle compilazioni di debug, ma si risolve in NULL nelle build retail. Viene usato in questo esempio per assegnare al componente un nome visualizzato nei log di debug, ma non occupa la memoria nella versione finale.

Il CreateInstance metodo può avere qualsiasi nome, perché la classe factory fa riferimento al puntatore della funzione nel modello di factory. Tuttavia, g_Templates e g_cTemplates sono variabili globali che la classe factory prevede di trovare, pertanto devono avere esattamente tali nomi.

Come creare una DLL del filtro DirectShow