HRESULT CoGetInterfaceAndReleaseStream( IStream *pStm, REFIID riid, void **ppv)
{
HRESULT hr = CoUnmarshalInterface(pStm, riid, ppv);
pStm->Release;
return hr;
}
Ни одна из этих двух функций не обеспечивает каких-либо особых возможностей, но в некоторых случаях удобнее использовать их, а не низкоуровневые аналоги.
Следующий фрагмент кода мог бы быть применен для передачи интерфейсного указателя в другой апартамент того же процесса с использованием глобальной переменной для хранения промежуточной маршалированной объектной ссылки:
HRESULT WritePtrToGlobalVarable(IRacer *pRacer)
{
// where to write the marshaled ptr
// куда записывать маршалированный указатель
extern IStream *g_pStmPtr;
// thread synchronization for read/write
// синхронизация потока для чтения/записи
extern HANDLE g_heventWritten;
// write marshaled object reference to global variable
// записываем маршалированную объектную ссыпку
// в глобальную переменную
HRESULT hr = CoMarshalInterThreadInterfaceInStream( IID_IRacer, pRacer, &g_pStmPtr);
// signal other thread that ptr is now available
// подаем сигнал другому процессу о том, что указатель
// теперь доступен
SetEvent (g_heventWritten); return hr; }
Соответствующий код будет корректно демаршалировать объектную ссылку в апартамент вызывающего объекта при условии, что он находится и том же самом процессе:
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;
}
Данный код требуется при передаче указателя от одного апартамента к другому[1]. Отметим, что при передаче указателя от потока, выполняющегося в
Отметим, что в приведенном коде программа считывания устанавливает в нуль глобальную переменную
[uuid(00000146-0000-0000-C000-000000000046), object, local ]
interface IGlobalInterfaceTable : IUnknown {
// marshal an Interface into the GIT
// маршалируем интерфейс в GIT