Если все запрошенные интерфейсы доступны в новом объекте, то
[object,uuid(753A8F7C-A7FF-11d0-8C30-0080C73925BA)]
interface IEgghead : IUnknown
{
import «unknwn.idl»;
HRESULT ContemplateNavel(void);
}
Имея такое определение интерфейса, клиент может привязать оба типа указателей к новому шимпанзе за одно обращение:
void CreateChimpEatBananaAndThinkAboutIt(void)
{
// declare and initialize an array of MULTI_QI's
// объявляем и инициализируем массив MULTI_QI
MULTI_QI rgmqi[2] = { { &IID_IApe, 0, 0 }, { &IID_IEgghead, 0, 0 } };
HRESULT hr = CoCreateInstanceEx( CLSID_Chimp,
// make a new chimp – создаем нового шимпанзе
0,
// no aggregation – без агрегирования
CLSCTX_ALL,
// any locality – размещение любое
0,
// no explicit host/security info
// нет явной информации о хосте и безопасности
2,
// asking for two interfaces – запрашиваем 2 интерфейса
rgmqi);
// array of MULTI_QI structs – массив структур
MULTI_QI
if (SUCCEEDED(hr)) {
// hr may be CO_S_NOTALLINTERFACES, so check each result
// hresult может быть равен CO_S_NOTALLINTERFACES,
// поэтому проверяем каждый результат
if (hr == S_OK || SUCCEEDED(rgmqi[0].hr)) {
// it is safe to blindly cast the resultant ptr to the type
// that corresponds to the IID used to request the interface
// безопасно вслепую преобразовать результирующий
// указатель к типу, соответствующему тому IID,
// который использовался при запросе интерфейса
IАре *рАре = reinterpret_cast
assert(pApe);
HRESULT hr2 = pApe->EatBanana;
assert(SUCCEEDED(hr2));
pApe->Release;
}
if(hr == S_OK || SUCCEEDED(rgmqi[1].hr)) {
IEgghead *peh = reinterpret_cast
assert(peh);
HRESULT hr2 = peh->ContemplateNavel;
assert(SUCCEEDED(hr2));
peh->Release;
}
} }
Рисунок 3.3 показывает шаги, которые предпринимаются
Использование
HRESULT CreateChimpAndEatBanana(void)
{
// declare and Initialize a MULTI_QI
// определяем и инициализируем MULTI_QI
MULTI_QI mqi = { &IID_IApe, 0, 0 };
HRESULT hr = CoCreateInstanceEx( CLSID_Chimp,
// make a new chimp – создаем нового шимпанзе
0,
// по aggregation – без агрегирования CLSCTX_ALL,
// any locality – любое расположение
0,
// no explicit host/security Info
// нет явной информации о хосте/безопасности
1,
// asking for one interface – запрашиваем один интерфейс
&mqi);
// array of MULTI_QI structs – массив структур
MULTI_QI
if (SUCCEEDED(hr))
{
IApe *pApe = reinterpret_cast
assert(pApe);
// use the new object – используем новый объект
hr = pApe->EatBanana;
// release the Interface pointer
// освобождаем указатель интерфейса
pApe->Release;
}
return hr;
}
Если нужен только один интерфейс и не передается
HRESULT CoCreateInstance( [in] REFCLSID rclsid,
// what kind of object? – какой тип объекта?
[in] IUnknown *pUnkOuter,
// for aggregation – для агрегирования
[in] DWORD dwClsCtx,
// locality? – размещение?
[in] REFIID riid,
// what kind of interface – какой вид интерфейса
[out, iid_is(riid)] void **ppv);
// where to put itf – куда разместить интерфейс
Предыдущий пример становится намного проще, если применить
HRESULT CreateChimpAndEatBanana(void)
{
IАре *рАре = 0;
HRESULT hr = CoCreateInstance( CLSID_Chimp,
// make a new chimp – создаем нового шимпанзе
0,
// по aggregation – без агрегирования
CLSCTX_ALL,
// any locality – любое расположение
IID_IApe,
// what kind of itf – какой вид интерфейса
(void**)&pApe);
// where to put iff – куда поместить интерфейс
if (SUCCEEDED(hr)) {
assert(pApe);
// use the new object используем новый объект
hr = pApe->EatBanana;
// release the interface pointer
// освобождаем указатель интерфейса
pApe->Release;
}
return hr;
}