HRESULT hr = LoadRegTypeLib(LIBID_PrimeLib, 1, 0, 0, &ptl);
assert(SUCCEEDED(hr));
hr = ptl->GetTypeInfoOfGuid(IID_DIPrimeManager, &m_pTypeInfo);
ptl->Release(); } virtual PrimeManager(void) { m_pTypeInfo->Release(); }
};
Имея приведенное выше определение класса, метод
STDMETHODIMP PrimeManager::GetTypeInfo (UINT it, LCID lcid, ITypeInfo **ppti) {
assert(it == 0 && ppti != 0);
(*ppti = m_pTypeInfo)->AddRef();
return S_OK;
}
Если бы объект поддерживал несколько локализованных библиотек типов, то реализации следовало бы использовать параметр
STDMETHODIMP PrimeManager::GetTypeInfoCount(UINT *pit) {
assert(pit != 0); *pit = 1;
// only 0 or 1 are allowed
// допускаются только 0 или 1
return S_OK;
}
Единственными допустимыми значениями счетчика являются нуль (это означает, что данный объект
Методы
STDMETHODIMP PrimeManager::GetIDsOfNames(REFIID riid, OLECHAR **pNames, UINT cNames, LCID lcid, DISPID *pdispids) {
assert(riid == IID_NULL);
return m_pTypeInfo->GetIDsOfNames(pNames, cNames, pdispids);
}
Поскольку библиотека типов содержит все имена методов и соответствующие им
STDMETHODIMP PrimeManager::Invoke(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pd, VARIANT *pVarResult, EXCEPINFO *pe, UINT *pu) {
assert(riid == IID_NULL);
void *pvThis = static_cast<DIPrimeManager*>(this);
return m_pTypeInfo->Invoke(pvThis, id, wFlags, pd, pVarResult, pe, pu);
}

Первым параметром
Двунаправленные интерфейсные контракты
Как было показано в главе 5, объекты, постоянно находящиеся в различных апартаментах, могут использовать сервисные программы друг друга вне зависимости от того, резидентом какого апартамента является другой объект. Поскольку удаленный доступ в СОМ основан на концепции апартаментов, разработчикам необходимо рассматривать процессы не как клиенты или серверы в чистом виде, а скорее как набор из одного или нескольких апартаментов, которые способны одновременно экспортировать и импортировать интерфейсы.
Как два объекта договариваются о том, чьи интерфейсы будут использоваться для взаимного сотрудничества, в значительной степени является спецификой области применения. Для примера рассмотрим следующий интерфейс, моделирующий программиста:
[uuid(75DA6457-DD0F-11d0-8C58-0080C73925BA),object]
interface IProgrammer : IUnknown {
HRESULT StartHacking(void);
HRESULT IsProductDone([out, retval] BOOL *pbIsDone);
}
Клиент будет использовать такой интерфейс следующим образом:
HRESULT ShipSoftware(void)
{
IProgrammer *pp = 0;
HRESULT hr = CoGetObject(OLESTR(«programmer:Bob»), 0,
IID_IProgrammer, (void**)&pp);
if (SUCCEEDED(hr)) {
hr = pp->StartHacking();
BOOL bIsDone = FALSE;
while (!bIsDone && SUCCEEDED(hr)) {
Sleep(15000);
// wait 15 seconds
// ожидаем 15 секунд
hr = pp->IsProductDone(&bIsDone);
// check status
// проверяем состояние