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



         

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


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

HRESULT ReadPtrFromGlobalVariable(IRacer * &rpRacer) { // where to write the marshaled ptr // куда записывать маршалированный указатель extern IStream *g_pStmPtr; // thread synchronization for read/write // синхронизация потока для чтения/записи 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 = CoGetInterfaceAndReleaseStream( g_pStmPtr, IID_IRacer. (void**) &rpRacer); // MSHLFLAGS_NORMAL means no more unmarshals are legal // MSHLFLAGS_NORMAL означает, что больше не может быть // извлечено никаких демаршалированных указателей g_pStmPtr = 0; return hr; }

Данный код требуется при передаче указателя от одного апартамента к другому. Отметим, что при передаче указателя от потока, выполняющегося в МТА или RTA, к другому потоку, выполняющемуся в том же апартаменте, не требуется никаких вызовов маршалинга. Тем не менее, обычной практикой для программы записи (writer) интерфейсного указателя является вызов AddRef до передачи копии в поток программы считывания (reader). Когда поток читающей программы выполняется с использованием указателя, ему, конечно, необходимо будет вызвать Release.

Отметим, что в приведенном коде программа считывания устанавливает в нуль глобальную переменную g_pStmPtr после демаршалинга. Это сделано потому, что объектная ссылка была маршалирована с флагом MSHLFLAGS_NORMAL и может быть демаршалирована только один раз. Во многих сценариях это не является проблемой. В некоторых других сценариях, однако, желательно маршалировать указатель из одного потока и иметь несколько рабочих потоков, в которых можно демаршалировать интерфейсный указатель по мере необходимости.


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