Какой способ получения COM-интерфейса используете вы?
Вопрос теоретического наклона, так как на практике - это несколько способов сделать одно и тоже, но с разной степенью абстракции (от более высоко уровня к низкоуровневому).
Далее в качестве примера возьмём интерфейс IDirectDraw7
- Код: Выделить всё
HRESULT hr;
LPDIRECTDRAW7 m_pDD;
1)Специализированная функция (если такая имеется для конкретного интерфейса)
- Код: Выделить всё
bool InitGraphics1(GUID *pDDrawGuid)
{
if(m_pDD)
return false;
hr = DirectDrawCreateEx(pDDrawGuid,
reinterpret_cast<void **>(&m_pDD),
IID_IDirectDraw7, NULL);
if(FAILED(hr))
return false;
return true;
}
2)Получения интерфейса через запрос в методе QueryInterface уже полученного интерфейса
- Код: Выделить всё
bool InitGraphics2(GUID *pDDrawGuid)
{
if(m_pDD)
return false;
LPDIRECTDRAW legacyDD = NULL;
hr = DirectDrawCreate(NULL, &legacyDD, NULL);
if(FAILED(hr))
return false;
if(legacyDD)
{
hr = legacyDD ->
QueryInterface(IID_IDirectDraw7,
reinterpret_cast<void **>(&m_pDD));
legacyDD -> Release();
}
legacyDD = NULL;
if(FAILED(hr))
return false;
return true;
}
Так как все COM интерфейсы наследники абстрактного IUnknown, у которого есть метод QueryInterface, через который можно получить любой интерфейс. А DirectDrawCreate может получить интерфейс до версии IDirectDraw7, но он здесь в качестве примера.
3)Получение через функцию общего назначения CoCreateInstance, с подготовкой по использованию COM.
- Код: Выделить всё
bool InitGraphics3(GUID *pDDrawGuid)
{
if(m_pDD)
return false;
hr = CoInitialize(NULL);
if(FAILED(hr))
return false;
//LaMothe use only CLSID_DirectDraw without 7. Why?
hr = CoCreateInstance(CLSID_DirectDraw,
NULL, CLSCTX_ALL, IID_IDirectDraw7,
reinterpret_cast<void **>(&m_pDD));
CoUninitialize();
if(FAILED(hr))
return false;
hr = m_pDD -> Initialize(pDDrawGuid);
if(FAILED(hr))
return false;
return true;
}
Собственно последний способ описан Андре Ламот и назван как рекомендованный Microsoft(возможно это касается только IDirectDraw7).