Шаблон фабрики
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
Шаблон фабрики содержит следующие открытые переменные-члены:
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)
Два указателя функций, m_lpfnNew и m_lpfnInit, используют следующие определения типов:
typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
Первый — это функция создания экземпляра для компонента. Второй — необязательная функция инициализации. Если вы предоставляете функцию инициализации, она вызывается из функции точки входа DLL. (Функция точки входа DLL рассматривается далее в этой статье.)
Предположим, вы создаете библиотеку DLL, содержащую компонент CMyComponent, который наследуется от CUnknown. В библиотеке DLL необходимо указать следующие элементы:
- Функция инициализации, открытый метод, который возвращает новый экземпляр CMyComponent.
- Глобальный массив шаблонов фабрики с именем g_Templates. Этот массив содержит шаблон фабрики для CMyComponent.
- Глобальная переменная с именем g_cTemplates , указывающая размер массива.
В следующем примере показано, как объявить эти элементы:
// 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]);
Метод CreateInstance
вызывает конструктор класса и возвращает указатель на новый экземпляр класса. Параметр pUnk — это указатель на агрегирование IUnknown. Этот параметр можно просто передать в конструктор класса. Параметр pHr является указателем на значение HRESULT. Конструктор класса присваивает ей соответствующее значение, но в случае сбоя конструктора задайте значение E_OUTOFMEMORY.
Макрос NAME создает строку в отладочных сборках, а в розничных сборках разрешается в NULL. В этом примере он используется для присвоения компоненту имени, которое отображается в журналах отладки, но не занимает память в окончательной версии.
Метод CreateInstance
может иметь любое имя, так как фабрика класса ссылается на указатель функции в шаблоне фабрики. Однако g_Templates и g_cTemplates являются глобальными переменными, которые фабрика классов ожидает найти, поэтому они должны иметь именно эти имена.
Связанные темы