сложилось исторически и никоим образом не означает использование разделяемой памяти.

После осмысления всех типов параметров API-функции CoMarshalInterface она выглядит достаточно просто:

HRESULT CoMarshalInterface(

[in] IStream *pStm,

// where to write marshaled state

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

[in] REFIID riid, // type of ptr being marshaled

// тип маршалируемого указателя

[in, iid_is(riid)] IUnknown *pItf,

// pointer being marshaled

// маршалируемый указатепь

[in] DWORD dwDestCtx,

// MSHCTX for destination apt.

// MSHCTX для апартамента адресата

[in] void *pvDestCtx,

// reserved, must be zero

// зарезервирован, должен равняться нулю

[in] DWORD dwMshlFlags

// normal, vs. table marshal

// нормальный маршалинг против табличного

);

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

HRESULT WritePtr(IRacer *pRacer, HGLOBAL& rhglobal)

{ IStream *pStm = 0; гhglobal = 0;

// alloc and wrap block of memory

// выделяем и заворачиваем блок памяти

HRESULT hr = CreateStreamOnHGlobal(0, FALSE, &pStm);

if (SUCCEEDED(hr)) {

// write marshaled object reference to memory

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

hr = CoMarshalInterface(pStm, IID_Iracer, pRacer, MSHCTX_DIFFERENTMACHINE, 0, MSHLFLAGS_NORMAL);

// extract handle to underlying memory

// извлекаем дескриптор памяти

if (SUCCEEDED(hr)) hr = GetHGlobalFromStream(pStm, &rhglobal);

pStm->Release();

}

return hr;

}

Рисунок 5.1 иллюстрирует взаимоотношения между интерфейсным указателем и памятью, содержащей маршалированную объектную ссылку. После вызова CoMarshalInterface апартамент объекта готов получить от другого апартамента запрос на соединение. Поскольку был использован флаг MSHCTX_DIFFERENTMACHINE, то импортирующий апартамент может находиться на другой хост-машине.

Для того чтобы декодировать маршалированную объектную ссылку, созданную в предыдущем фрагменте кода, в нормальный интерфейсный указатель, импортирующему апартаменту необходимо вызвать API-функцию CoUnmarshalInterface :

HRESULT CoUnmarshalInterface(

[in] IStream *pStm,

// where to read marshaled state

// откуда читать маршалированное состояние

[in] REFIID riid, // type of ptr being unmaгshaled

// тип демаршалируемого указателя

[out, iid_is(riid)] void **ppv

// where to put unmarshaled ptr

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

);

CoUnmarshalInterface просто читает преобразованную в последовательную форму объектную ссылку и возвращает указатель на исходный объект, к которому есть легальный доступ в апартаменте вызывающего потока. Если импортирующий апартамент отличается от того апартамента, который изначально экспортировал интерфейс, то результирующий указатель будет указателем на заместитель. Если по какой-то причине вызов CoUnmarshalInterface осуществлен из исходного апартамента, где располагается объект, то в этом случае будет возвращен указатель на сам объект и не будет создано никакого заместителя. Следующий код переводит маршалированную объектную ссылку в нормальный указатель интерфейса:

HRESULT ReadPtr(HGLOBAL hglobal, IRacer * &rpRacer) {

IStream *pStm = 0; rpRacer = 0;

// wrap block of existing memory passed on input

// заключаем в оболочку блок существующей памяти,

// переданный на вход

HRESULT hr = CreateStreamOnHGlobal(hglobal, FALSE, &pStm);

if (SUCCEEDED(hr)) {

// get a pointer to the object that is legal in this apt.

// получаем указатель на объект, легальный в этом апартаменте

hr = CoUnmarshalInterface(pStm, IID_Iracer, (void**)&rpRacer);

pStm->Release();

}

return hr;

}

Результирующий заместитель будет реализовывать каждый из экспортируемых объектом интерфейсов путем переадресации запросов методов в апартамент объекта.

До появления выпуска СОМ под Windows NT 4.0 формат маршалированной объектной ссылки не был документирован. Для того чтобы позволить сторонним участникам создавать сетевые продукты, совместимые с СОМ, этот формат был документирован для открытого использования в 1996 году и

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату