Сущность технологии СОМ. Библиотека программиста | страница 98
После постижения структуры MULTI_QI понять определение CoCreateInstanceEx уже нетрудно:
HRESULT CoCreateInstanceEx( [in] REFCLSID rclsid,
// what kind of object? – какого сорта объект?
[in] IUnknown *pUnkOuter,
// for aggregation – для агрегирования
[in] DWORD dwClsCtx,
// locality? – размещение?
[in] COSERVERINFO *pcsi,
// host/security info – информация о хосте/безопасности
[in] ULONG cmqi,
// how many interfaces? – сколько интерфейсов?
[out, size_is (cmqi)] MULTI_QI *prgmq
// where to put itfs – куда разместить интерфейсы );
Если все запрошенные интерфейсы доступны в новом объекте, то CoCreateInstanceEx возвращает S_OK. Если хотя бы один (но не все) из запрошенных интерфейсов недоступен, то CoCreateInstanceEx возвратит CO_S_NOTALLINTERFACES, индицируя частичный успех. Затем вызывающий объект должен исследовать индивидуальные HRESULT в каждой структуре MULTI_QI, чтобы определить, какие интерфейсы были доступны, а какие – нет. Если CoCreateInstanceEx не может создать объект или ни один из запрошенных интерфейсов не доступен, то CoCreateInstanceEx возвращает HRESULT с кодом серьезности ошибки SEVERITY_ERROR, который сообщит, почему произошел отказ в операции.
CoCreateInstanceEx чрезвычайно эффективен в случае, когда требуются интерфейсы нескольких типов. Рассмотрим дополнительное определение интерфейса:
[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 – размещение любое