выполняет вызовы
Похоже на то, что по меньшей мере один из методов
STDMETHODIMP Rect::get_Area(long *pn) {
long top, left, bottom, right;
HRESULT hr = m_pPtTopLeft->GetCoords(&left, &top);
assert(SUCCEEDED(hr));
hr = m_pPtBottomRight->GetCoords(&right, &bottom);
assert (SUCCEEDED (hr));
*pn = (right – left) * (bottom – top);
return S_OK;
}
Если бы класс
Это оставляет разработчику
class SafeRect : public IRect {
LONG m_cRef;
// СОМ reference count
// счетчик ссылок СОМ IUnknown *m_pUnkFTM;
// cache for FTM lazy aggregate
// кэш для отложенного агрегирования FTM
DWORD m_dwTopLeft;
// GIT cookie for top/left
// закладка GIT для верхнего/левого
DWORD m_dwBottomRight;
// GIT cookie for bottom/right
// закладка GIT для нижнего/правого
Разработчик по-прежнему создает два экземпляра
SafeRect::SafeRect(void) : m_cRef(0), m_pUnkFTM(0) {
// assume ptr to GIT is initialized elsewhere
// допустим, что указатель на GIT инициализирован
// где-нибудь в другом месте
extern IGIobalInterfaceTable *g_pGIT;
assert(g_pGIT != 0);
IPoint *pPoint = 0;
// create instance of class Point
// создаем экземпляр класса Point HRESULT
hr = CoCreateInstance(CLSID_Point, 0, CLSCTX_INPROC, IID_Ipoint, (void**)&pPoint);
assert (SUCCEEDED (hr));
// register interface pointer in GIT
// регистрируем интерфейсный указатель в GIT
hr = g_pGIT->RegisterInterfaceInGlobal(pPoint, IID_Ipoint, &m_dwTopLeft);
assert(SUCCEEDED(hr));
pPoint->Release();
// reference is now held in GIT
// ссылка теперь содержится в GIT
// create instance of class Point
// создаем экземпляр класса Point
hr = CoCreateInstance(CLSID_Point, 0, CLSCTX_INPROC, IID_Ipoint, (void**)&pPoint);
assert(SUCCEEDED(hr));
// register interface pointer in GIT
// регистрируем интерфейсный указатель в GIT
hr = g_pGIT->RegisterInterfaceInGlobal(pPoint, IID_Ipoint, &m_dwBottomRight);
assert(SUCCEEDED(hr)); pPoint->Release();
// reference is now held in GIT
// ссылка теперь содержится в GIT
}
Отметим, что все то время, пока интерфейсный указатель зарегистрирован в GIT, пользователь интерфейсного указателя не должен хранить никаких дополнительных ссылок.
Поскольку класс был преобразован для использования GIT вместо исходных интерфейсных указателей, он должен демаршалировать новый заместитель в каждом вызове метода, которому требуется доступ к зарегистрированным интерфейсам:
STDMETHODIMP SafeRect::get_Area(long *pn) {
extern IGlobalInterfaceTable *g_pGIT; assert(g_pGIT != 0);
// unmarshal the two interface pointers from the GIT
// демаршалируем дВа интерфейсных указателя из GIT
IPoint *ptl = 0, *pbr = 0;
HRESULT hr = g_pGIT->GetInterfaceFromGlobal(m_dwPtTopLeft, IID_Ipoint, (void**)&ptl);
assert (SUCCEEDED(hr));
