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

Тут можно читать онлайн Дональд Бокс - Сущность технологии СОМ. Библиотека программиста - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Питер, год 2001. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Сущность технологии СОМ. Библиотека программиста
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2001
  • Город:
    СПб
  • ISBN:
    5-318-00058-4
  • Рейтинг:
    4/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

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

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

Интервал:

Закладка:

Сделать

else if (riid = IID_IVehicle) *ppv = static_cast(this);

else if (riid == IID_ICar) *ppv = static_cast(this);

else return (*ppv = 0), E_NOINTERFACE;

((IUnknown*)*ppv)->AddRef();

return S_OK;

}

STDMETHODIMP_(ULONG) Car::InternalAddRef(void)

{

return InterlockedIncrement(&m_cRef);

}

STDMETHODIMP_(ULONG) Car::InternalRelease(void)

{

ULONG res = InterlockedDecrement(&m_cRef);

if (res == 0) delete this;

return res;

}

Единственной отличительной особенностью этих трех методов (кроме их имен) является то, что InternalQueryInterface при запросе IUnknown возвращает указатель на неделегирующую Unknown . Это просто требование Спецификации СОМ, которого следует придерживаться.

И наконец, подпрограмму создания Car требуется модифицировать для поддержки агрегирования:

STDMETHODIMP CarClass::CreateInstance(IUnknown *punk0uter, REFIID riid, void **ppv)

{

// verify that aggregator only requests IUnknown as

// initial interface

// проверяем, что агрегатор только запрашивает IUnknown как

// начальный интерфейс

if (pUnkOuter != 0 && riid != IID_IUnknown)

return (*ppv = 0), E_INVALIDARG;

// create new object/aggregate

// создаем новый объект или агрегат Car

*р = new Car(pUnkOuter);

if (!p) return (*ppv = 0), E_OUTOFMEMORY;

// return resultant pointer

// возвращаем результирующий указатель

p->InternalAddRef();

HRESULT hr = p->InternalQueryInterface(riid, ppv);

p->InternalRelease();

return hr;

}

Отметим, что здесь используются неделегирующие версии QueryInterface , AddRef и Release . Если создается автономная идентификационная единица, то это, конечно, допустимо. Если же создается агрегат, то необходимо убедиться, что AddRef обработал внутренний, а не внешний объект. Отметим также, что внешний объект в качестве начального интерфейса должен запросить IUnknown . Все это регламентировано Спецификацией СОМ. Если бы внешний объект мог запрашивать произвольный начальный интерфейс, то внутреннему объекту пришлось бы хранить два дублирующих набора указателей vptr : один набор делегировал бы свои реализации QueryInterface , AddRef и Release , а другой – нет. При допущении в качестве начального интерфейса одного IUnknown разработчик объекта может выделить только один vptr , который будет действовать как неделегирующий IUnknown .

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

Еще одна проблема при программировании агрегирования может возникнуть, когда необходимо связать между собой внутренний и внешний объекты. Для того чтобы организовать связь внутреннего объекта с внешним, нужно вызвать QueryInterface посредством управляющего IUnknown . Однако этот запрос QueryInterface вызовет AddRef через результирующий указатель, который имеет обыкновение без спросу обрабатывать внешний объект с помощью AddRef . Если бы внутренний объект хранил этот указатель в качестве элемента данных, то возник бы цикл, поскольку внутренний объект уже неявно обработал внешний объект с помощью AddRef . Это означает, что внутренний объект должен избрать одну из двух стратегий. Внутренний объект может получать и освобождать указатель по потребности, храня его ровно столько времени, сколько это необходимо:

STDMETHODIMP Inner::MethodX(void)

{

ITruck *pTruck = 0;

// outer object will be AddRefed after this call…

// после этого вызова внешний объект будет обработан

// с помощью AddRef…

HRESULT hr = m_pUnkOuter->QueryInterface(IID_ITruck, (void**)&pTruck);

if (SUCCEEDED(hr))

{

pTruck->ShiftGears();

pTruck->HaulDirt();

// release reference to outer object

// освобождаем ссылку на внешний объект pTruck->Release();

}

}

Второй способ заключается в том, чтобы получить указатель один раз во время инициализации и освободить соответствующий внешний объект немедленно после получения.

HRESULT Inner::Initialize(void)

{

// outer object will be AddRefed after this call…

// после этого вызова внешний объект будет обработан

// с помощью AddRef…

HRESULT hr = m_pUnkOuter->QueryInterface(IID_ITruck, (void**)&m_pTruck);

// release reference to outer object here and DO NOT

// release it later in the object's destructor

// освобождаем здесь ссылку на внешний объект и

// НЕ ОСВОБОЖДАЕМ ее потом в деструкторе объекта

if (SUCCEEDED(hr)) m_pTruck->Release();

}

Этот способ работает, поскольку время жизни внутреннего объекта является точным подмножеством времени жизни внешнего объекта. Это означает, что m_pTruck будет теоретически всегда указывать на существующий объект. Конечно, если внешний объект реализовал ITruck как отделяемый интерфейс, то все предыдущее неверно, так как вызов Release уничтожит этот отделяемый интерфейс.

Объекты, которые агрегируют другие объекты, должны быть в курсе проблем, возникающих при запросе интерфейсных указателей внутренними объектами агрегата. В дополнение к уже сделанному предостережению относительно отделяемых интерфейсов отметим еще одну возможную опасность, связанную со стабилизацией объекта. Когда клиенты обращаются к объекту, он должен находиться в стабильном состоянии. В частности, его счетчик ссылок не должен равняться нулю. В общем случае это не является проблемой, так как клиенты могут получать интерфейсные указатели только через QueryInterface , который всегда освобождает AddRef раньше, чем возврат. Однако если объект создает агрегат в своем разработчике, в то время как его счетчик ссылок объекта равен нулю, то программа инициализации внутреннего объекта, показанная выше, освободит завершающее освобождение внешнего объекта, побуждая тем самым внешний объект к преждевременному самоуничтожению. Чтобы устранить эту проблему, объекты, агрегирующие другие объекты, временно увеличивают свои счетчики ссылок на единицу на время создания агрегируемых объектов:

Outer::Outer(void)

{

++m_cRef;

// protect against delete this

// защищаем против удаления this

CoCreateInstance(CLSID_Inner, this, CLSCTX_ALL, IID_IUnknown, (void**)&m_pUnkInner);

–m_cRef;

// allow delete this

// позволяем удалить this }

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Дональд Бокс читать все книги автора по порядку

Дональд Бокс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x