[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); }
Клиенты получают доступ к
Для того чтобы сделать интерфейсный указатель доступным для всех апартаментов процесса, апартамент, содержащий этот интерфейсный указатель, должен зарегистрировать его в
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; }
Отметим принципиальную разницу между этими фрагментами кода и примерами с применением
Архитектура стандартного маршалинга
Как уже упоминалось ранее в этой главе, СОМ использует протокол ORPC для всех обращений между апартаментами. Это обстоятельство может представлять интерес с точки зрения архитектуры, но некоторые разработчики желают программировать коммуникационный код низкого уровня. Для того чтобы воспользоваться ORPC-коммуникациями, объектам СОМ не требуется делать ничего, кроме реализации IUnknown, для осуществления межапартаментных обращений по протоколу ORPC. По умолчанию при первом вызове CoMarshalInterface для объекта этот объект опрашивается, желает ли он управлять своими собственными межапартаментными связями. Этот вопрос приходит в форме запроса QueryInterface об интерфейсе IMarshal. Большинство объектов не реализуют интерфейс IMarshal и дают отказ на этот запрос со стороны QueryInterface, показывая тем самым, что их вполне удовлетворяет управление всеми связями самой СОМ посредством вызовов ORPC. Те объекты, которые реализуют интерфейс IMarshal, показывают этим, что ORPC им не подходит и что разработчик объекта предпочитает управлять всеми межапартаментными связями посредством специальных заместителей. Когда объект реализует интерфейс IMarshal, то все ссылки на этот объект будут подвергнуты специальному маршалингу. Специальный