В предыдущем примере интерфейс IApeClass рассматривался как интерфейс уровня класса, специфический для классов, которые объявляют интерфейс IАре из своих экземпляров. Этот интерфейс позволяет клиентам создавать новые объекты или находить существующие, но в любом случае результирующие объекты должны реализовывать интерфейс IАре. Если бы новый класс хотел разрешить клиентам создавать или находить объекты, несовместимые с IApe, то объект этого класса должен был бы реализовывать другой интерфейс. Поскольку создание и поиск объектов являются общими требованиями, которые большинство классов хотели бы поддерживать, СОМ определяет стандартные интерфейсы для моделирования поиска и создания объектов унифицированным образом (generically). Один стандартный интерфейс для поиска объектов назван IOleItemContainer:
// from oleidl.idl из oleidl.idl
[ object, uuid(0000011c-0000-0000-C000-000000000046) ] interface IOleItemContainer : IOleContainer { // ask for object named by pszItem // запрашиваем объект, именованный pszItem HRESULT Get0bject( [in] LPOLESTR pszItem, // which object? какой объект? [in] DWORD dwSpeedNeeded, // deadline [in, unique] IBindCtx *pbc, // binding info информация о связывании [in] REFIID riid, // which interface? какой интерфейс? [out, iid_is(riid)] void **ppv); // put it here! разместим его здесь!
// remaining methods deleted for clarity // остальные методы удалены для ясности }
Отметим, что метод GetObject позволяет клиенту задавать тип результирующего интерфейсного указателя. Действительный класс результирующего объекта зависит от контекста и конкретной реализации IOleItemContainer. Следующий пример запрашивает объект класса Gorilla найти объект под именем "Ursus":
HRESULT FindUrsus(IApe * &rpApe) { // bind a reference to the class object // связываем ссылку с объектом класса rpApe = 0; IOleItemContainer *poic = 0; HRESULT hr = CoGetClassObject(CLSID_Gorilla, CLSCTX_ALL, 0, IID_IOleItemContainer, (void**)&poic); if (SUCCEEDED(hr)) { // ask Gorilla class object for Ursus // запрашиваем объект класса Gorilla на поиск Ursus hr = poic->GetObject(OLESTR("Ursus"), BINDSPEED_INDEFINITE, 0, IID_IApe, (void**)&rpApe); poic->Release(); } return hr; }