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



         

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


Клиенты получают доступ к 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; }




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