Сущность технологии COM



         

Вспомогательные средства для внутрипроцессного маршалинга - часть 3


Если все рабочие потоки выполняются в МТА, то это не является проблемой, поскольку нужно выполнить демаршалинг только в одном потоке — от имени всех потоков, выполняющихся в МТА. Если, однако, рабочие потоки выполняются в произвольных апартаментах, то этот подход не сработает, поскольку тогда придется независимо демаршалировать объектную ссылку в каждом рабочем потоке. Большинство разработчиков в этом случае обращаются к флагу MSHLFLAGS_TABLESTRONG, надеясь на однократный маршалинг и столько демаршалингов, сколько необходимо (по одному разу на апартамент). К сожалению, табличный маршалинг (в отличие от обычного маршалинга) не поддерживается в случае, если исходный указатель является заместителем, что случается часто, особенно в распределенных приложениях. Для разрешения этой проблемы в выпуске СОМ Service Pack 3 под Windows NT 4.0 вводится Глобальная интерфейсная таблипа (Global Interface Table - GIT).

GIT является оптимизацией CoMarshalInterface / CoUnmarshalInterface, которая допускает обращение к интерфейсным указателям из всех апартаментов процесса. Внутри СОМ реализуется одна GIT на процесс. GIT содержит маршалированные интерфейсные указатели, которые могут быть эффективно демаршалированы несколько раз внутри одного и того же процесса. Это семантически эквивалентно использованию табличного маршалинга, однако GIT можно использовать как для объектов, так и для заместителей. GIT выставляет интерфейс IGlobalInterfaceTable:

[uuid(00000146-0000-0000-C000-000000000046), object, local ] interface IGlobalInterfaceTable : IUnknown { // marshal an Interface into the GIT // маршалируем интерфейс в GIT HRESULT RegisterInterfaceInGlobal ( [in, iid_is(riid)] IUnknown *pItf, [in] REFIID riid, [out] DWORD *pdwCookie); // destroy the marshaled object reference // уничтожаем маршалированную объектную ссылку HRESULT RevokeInterfaceFromGlobal ( [in] DWORD dwCookle); // unmarshal an interface from the GIT // демаршалируем интерфейс из GIT HRESULT GetInterfaceFromGlobal ( [in] DWORD dwCookie, [in] REFIID riid, [out, iid_is(riid)] void **ppv); }




Содержание  Назад  Вперед