-->

Сущность технологии СОМ. Библиотека программиста

На нашем литературном портале можно бесплатно читать книгу Сущность технологии СОМ. Библиотека программиста, Бокс Дональд-- . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Сущность технологии СОМ. Библиотека программиста
Название: Сущность технологии СОМ. Библиотека программиста
Дата добавления: 16 январь 2020
Количество просмотров: 277
Читать онлайн

Сущность технологии СОМ. Библиотека программиста читать книгу онлайн

Сущность технологии СОМ. Библиотека программиста - читать бесплатно онлайн , автор Бокс Дональд

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

1 ... 71 72 73 74 75 76 77 78 79 ... 118 ВПЕРЕД
Перейти на страницу:

template <class Itf, const IID* piid> class GlobalInterfacePointer {

DWORD m_dwCookie;

// the GIT cookie

// «закладка» GIT

// prevent misuse

// предотвращаем неправильное использование

GlobalInterfacePointer(const GlobalInterfacePointer&);

void operator =(const GlobalInterfacePointer&);

public:

// start as invalid cookie

// начинаем как неправильная «закладка»

GlobalInterfacePointer(void) : m_dwCookie(0) { }

// start with auto-globalized local pointer

// начинаем с автоматически глобализованным локальным указателем

GlobalInterfacePointer(Itf *pItf, HRESULT& hr) : m_dwCookie(0)

{ hr = Globalize(pItf); }

// auto-unglobalize

// осуществляем автоматическую деглобапизацию

~GlobalInterfacePointer(void) { if(m_dwСооkiе) Unglobalize() ; }

// register an interface pointer in GIT

// регистрируем интерфейсный указатель в GIT

HRESULT Globalize(Itf *pItf) { assert (g_pGIT != 0 && m_dwCookie == 0);

return g_pGIT->RegisterInterfaceInGlobal(pItf, * piid, &m_dwCookie);

}

// revoke an interface pointer in GIT

// аннулируем интерфейсный указатель в GIT

HRESULT Unglobalize(void) {

assert(g_pGIT != 0 && m_dwCookie != 0);

HRESULT hr = g_pGIT->RevokeInterfaceFromGlobal(m_dwCookie);

m_dwCookie = 0;

return hr;

}

// get а local interface pointer from GIT

// получаем локальный интерфейсный указатель из GIT

HRESULT Localize(Itf **ppItf) const {

assert(g_pGIT != 0 && m_dwCookie != 0);

return g_pGIT->GetInteгfaceFromGlobal(m_dwCookie, *piid, (void**)ppItf);

}

// convenience methods

// методы для удобства

bool IsOK(void) const { return m_dwCookie != 0; }

DWORD GetCookie(void) const { return m_dwCookie; }

};

#define GIP(Itf) GlobalInterfacePointer<Itf, &IID_##Itf>

Имея данное определение класса и макрос, класс SafeRect теперь вместо исходных DWORD сохраняет GlobalInterfacePointers:

class SafeRect : public IRect {

LONG m_cRef:

// СОM reference count

// счетчик ссылок СОМ

IUnknown *m_pUnkFTM;

// cache for FTM lazy aggregate

// кэш дпя отложенного агрегирования FTM

GIP(IPoint) m_gipTopLeft;

// GIT cookie – top/left

// «закладка» GIT для верхнего/левого элемента

GIP(IPoint) m_gipBottomRight;

// GIT cookie – bottom/right

// «закладка» GIT для нижнего/правого элемента

:

:

:

}

Для инициализации элемента GlobalInterfacePointer разработчик (который выполняется в апартаменте объекта) просто регистрирует обрабатываемые указатели, вызывая метод Globalize на каждый GlobalInterfacePointer:

SafeRect::SafeRect(void) : m_cRef (0), m_pUnkFTM(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 = m_gipTopLeft.Globalize(pPoint);

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_Iроint, (void**) &рРоint);

assert(SUCCEEDED(hr));

// register interface pointer in GIT

// регистрируем интерфейсный указатель в GIT

hr = m_gipBottomRight.Globalize(pPoint);

assert (SUCCEEDED (hr));

pPoint->Release();

// reference is now held in GIT

// теперь ссылка хранится в GIT

}

Те методы, которым нужен доступ к глобализованным указателям, могут импортировать локальную копию посредством метода Localize из GlobalInterfaсePointer:

STDMETHODIMP SafeRect::get_Top(long *pVal) {

IPoint *pPoint = 0;

// local imported pointer

// локальный импортированный указатель

HRESULT hr = m_gipTopLeft.Localize(&pPoint);

if (SUCCEEDED(hr)){

long x;

hr = pPoint->get_Coords(&x, pVal);

pPoint->Release(); }

return hr;

}

Отметим, что в силу применения маршалера свободной поточной обработки (FreeThreaded Marshaler) исходный интерфейсный указатель не может быть кэширован, а должен импортироваться при каждом вызове метода, чтобы предотвратить попытку доступа из неверного апартамента.

Предыдущий фрагмент кода может быть автоматизирован еще больше. Поскольку большинство вызовов методов в классе GlobalInterfacePointer должны будут локализовать временный указатель в самом вызове метода, то приводимый ниже класс автоматизирует импорт временного указателя и его последующее освобождение, что очень напоминает интеллектуальный указатель (smart pointer):

template <class Itf, const IID* piid> class LocalInterfacePointer {

Itf *m_pItf;

// temp imported pointer

// временный импортированный указатель

// prevent misuse

// предотвращаем неверное использование

LocalInterfacePointer(const LocalInterfacePointer&);

operator = (const LocalInterfacePointer&);

public:

LocalInterfacePointer(const GlobalInterfacePointer<Itf, piid>& rhs, HRESULT& hr) { hr = rhs.Loca1ize(&m_pItf) ; }

LocalInterfacePointer(DWORD dwCookie, HRESULT& hr) { assert(g_pGIT != 0);

hr = g_pGIT-&gtGetInterfaceFromGlobal(dwCookie, *piid, (void**)&m_pItf); }

~LocalInterfacePointer(void) { if (m_pItf) m_pItf->Release(); }

class SafeItf : public Itf { STDMETHOD_(ULONG, AddRef) (void) = 0;

// hide

// скрытый STDMETHOD_(ULONG, Release)(void) = 0;

// hide

// скрытый

};

SafeItf *GetInterface(void) const { return (SafeItf*) m_pItf; }

SafeItf *operator ->(void) const { assert(m_pItf != 0);

return GetInterface();

}

};

#def1ne LIP(Itf) LocalInterfacePointer<Itf, &IID_##Itf>

С получением этого второго класса C++ обработка импортированных указателей становится намного проще:

STDMETHODIMP SafeRect::get_Area(long *pn) {

long top, left, bottom, right;

HRESULT hr, hr2;

// import pointers

// импортируем указатели

LIP(IPoint) lipTopLeft(m_gipTopLeft, hr);

LIP(IPoint) lipBottomRight(m_gipBottomRight, hr2);

assert(SUCCEEDED(hr) && SUCCEEDED(hr2));

// use temp tocal pointers

// используем временные локальные указатели

hr = lipTopLeft->GetCoords(&left, &top);

hr2 = lipBottomRight->GetCoords(&right, &bottom);

assert(SUCCEEDED(hr) && SUCCEEDED(hr2));

*pn = (right – left) * (bottom – top); return S_OK;

// LocalInterfacePointer auto-releases temp ptrs.

// LocalInterfacePointer сам освобождает

// временные указатели

}

Макросы GIP и LIP делают совместное использование GIT и FTM намного менее громоздким. До появления GIT использование FTM в классе с интерфейсными указателями было значительно более трудным, чем теперь обеспечивает любой из кодов, приведенных в данном разделе.

Где мы находимся?

В данной главе была описана абстракция апартаментов как логическое группирование объектов, которые подчиняются правилам параллелизма и реентерабельности. Процессы имеют один или более апартаментов. Потоки выполняются в ровно одном апартаменте, а для реализации межапартаментных связей СОМ поддерживает маршалинг объектных ссылок через границы апартаментов. Заместитель является локальным представителем объекта, постоянно находящимся в другом апартаменте. Стандартные заместители для передачи запросов методов с удаленного объекта используют ORPC. Специальные заместители имеют полную свободу для обеспечения корректной семантики. Апартамент является фундаментальной абстракцией, которая используется во всей архитектуре удаленного доступа модели СОМ.

1 ... 71 72 73 74 75 76 77 78 79 ... 118 ВПЕРЕД
Перейти на страницу:
Комментариев (0)
название