Tableau de modèles de fabrique

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Le modèle de fabrique contient les variables membres publiques suivantes :

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)

Les deux pointeurs de fonction , m_lpfnNew et m_lpfnInit, utilisent les définitions de type suivantes :

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

La première est la fonction d’instanciation pour le composant. La seconde est une fonction d’initialisation facultative. Si vous fournissez une fonction d’initialisation, elle est appelée à partir de la fonction de point d’entrée DE DLL. (La fonction de point d’entrée DLL est décrite plus loin dans cet article.)

Supposons que vous créez une DLL qui contient un composant nommé CMyComponent, qui hérite de CUnknown. Vous devez fournir les éléments suivants dans votre DLL :

  • Fonction d’initialisation, méthode publique qui retourne une nouvelle instance de CMyComponent.
  • Tableau global de modèles de fabrique, nommé g_Templates. Ce tableau contient le modèle de fabrique pour CMyComponent.
  • Variable globale nommée g_cTemplates qui spécifie la taille du tableau.

L’exemple suivant montre comment déclarer ces éléments :

// 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]);    

La CreateInstance méthode appelle le constructeur de classe et retourne un pointeur vers la nouvelle classe instance. Le paramètre pUnk est un pointeur vers l’agrégation IUnknown. Vous pouvez simplement passer ce paramètre au constructeur de classe. Le paramètre pHr est un pointeur vers une valeur HRESULT. Le constructeur de classe définit cette valeur sur une valeur appropriée, mais si le constructeur échoue, définissez la valeur sur E_OUTOFMEMORY.

La macro NAME génère une chaîne dans les builds de débogage, mais elle est résolue en NULL dans les builds de vente au détail. Il est utilisé dans cet exemple pour donner au composant un nom qui apparaît dans les journaux de débogage, mais qui n’occupe pas la mémoire dans la version finale.

La CreateInstance méthode peut avoir n’importe quel nom, car la fabrique de classe fait référence au pointeur de fonction dans le modèle de fabrique. Toutefois, g_Templates et g_cTemplates sont des variables globales que la fabrique de classe s’attend à trouver. Elles doivent donc avoir exactement ces noms.

Guide pratique pour créer une DLL de filtre DirectShow