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

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); }


Клиенты получают доступ к GIT для своего процесса, вызывая CocreateInstance с использованием класса CLSID_StdGlobalInterfaceTable. Каждый вызов CoCreateInstance с применением этого CLSID возвращает указатель на одну и ту же GIT в процессе. Так же как к интерфейсу IStream, возвращенному CoMarshalInterThreadInterfaceInStream, к интерфейсным указателям на GIT можно обратиться из любого апартамента без обязательного маршалинга.

Для того чтобы сделать интерфейсный указатель доступным для всех апартаментов процесса, апартамент, содержащий этот интерфейсный указатель, должен зарегистрировать его в GIT путем вызова метода RegisterInterfaceInGlobal. GIT вернет вызывающей программе DWORD, который представляет глобальный указатель для всех апартаментов процесса. Этот DWORD может быть использован из любого апартамента процесса для демаршалинга нового заместителя путем вызова метода GetInterfaceFromGlobal. Этот же DWORD можно использовать для повторного демаршалинга заместителей до тех пор, пока вызов RevokeInterfaceFromGlobal не объявит глобальный интерфейсный указатель недействительным. Приложения, использующие эту глобальную интерфейсную таблицу (GIT ), обычно связывают один интерфейсный указатель на весь процесс при запуске:


IGlobalInterfaceTable *g_pGIT = 0; HRESULT Init0nce(void) {

assert(g_pGIT == 0);

return CoCreateInstance(CLSID_StdGlobalInterfaceTable, 0, CLSCDX_INPROC_5ERVER, IID_IGlobalInterfaceTable, (void**)&g_pGIT);

}


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


HRESULT WritePtrToGlobalVariable(IRacer *pRacer) {

// where to write the marshaled ptr

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

DWORD g_dwCookie;

// thread synchronization

// синхронизация потока extern HANDLE g_heventWritten;

// write marshaled object reference to global variable

// записываем маршалированную объектную ссыпку в глобальную переменную

HRESULT hr = g_pGIT->RegisterInterfaceInGlobal( pRacer, IID_IRacer, &g_dwCookie);

// signal other thread that ptr is now available

// сообщаем другому потоку о доступности указателя SetEvent(g_heventWritten); return hr; }


Следующий код корректно демаршалирует объектную ссылку и может вызываться из любого апартамента одного и того же процесса:


HRESULT ReadPtrFromGlobalVariable(IRacer * &rpRacer, bool bLastUnmarshal) {

// where to write the marshaled ptr

// куда записывать маршалированный указатель extern DWORD g_dwCookie;

// thread synchronization

// синхронизация потока extern

HANDLE g_heventWritten;

// wait for other thread to signal that ptr is available

// ожидаем другой поток, чтобы сигнализировать о доступности указателя

WaitForSingleObject(g_heventWritten, INFINITE);

// read marshaled object reference from global variable

// читаем маршалированную объектную ссылку из глобальной переменной

HRESULT hr = g_pGIT->GetInterfaceFromGlobal( g_dwCookie, IID_IRacer, (void**)&rpRacer);

// if we are the last to unmarshal, revoke the pointer

// если мы поспедние в очереди на демаршалинг, то

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

if (bLastUnmarshal) g_pGIT->RevokeInterfaceFromGlobal(g_dwCookie);

return hr; }


Отметим принципиальную разницу между этими фрагментами кода и примерами с применением CoMarshalInterThreadInterfaceInStream. Она состоит в том, что код, основанный на GIT, способен демаршалировать более чем один заместитель.


Архитектура стандартного маршалинга

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных
Язык программирования Euphoria. Справочное руководство
Язык программирования Euphoria. Справочное руководство

Euphoria (юфо'ри, также рус. эйфори'я, ра'дость) — язык программирования, созданный Робертом Крейгом (Rapid Deployment Software) в Канаде, Торонто. Название Euphoria — это акроним для «End-User Programming with Hierarchical Objects for Robust Interpreted Applications».Euphoria — интерпретируемый императивный язык высокого уровня общего назначения. C помощью транслятора из исходного кода на Euphoria может быть сгенерирован исходный код на языке Си, который в свою очередь может быть скомпилирован в исполнияемый файл или динамическую библиотеку при помощи таких компиляторов, как GCC, OpenWatcom и др. Программа Euphoria также может быть «связана» с интерпретатором для получения самостоятельного исполняемого файла. Поддерживается несколько GUI-библиотек, включая Win32lib и оберток для wxWidgets, GTK+ и IUP. Euphoria имеет встроенную простую систему баз данных и обертки для работы с другими типам баз данных.[Материал из Википедии]

Коллектив авторов

Программирование, программы, базы данных