MSHCTX_DIFFERENTMACHINE = 2

// off-host

// внехостовый

} MSHCTX;

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

typedef enum tagMSHLFLAGS

{

MSHLFLAGS_NORMAL,

// marshal once, unmarshal once

// маршалируем один раз, демаршалируем один раз

MSHLFLAGS_TABLESTRONG,

// marshal опсе, unmarshal many

// маршалируем один раз. демаршалируем много раз

MSHLFLAGS_TABLEWEAK,

// marshal once, unmarshal many

// маршалируем один раз, демаршалируем много раз

MSHLFLAGS_NOPING = 4,

// suppress dist. garbage collection

// подавляем ненужный набор дистанций

} MSHLFLAGS;

Нормальный (normal) маршалинг, иногда его называют еще маршалингом вызовов (call marshaling), означает, что маршалированная объектная ссылка должна быть демаршалирована только один раз, а если нужны дополнительные заместители, то требуются дополнительные вызовы CoMarshalInterface. Табличный (table) маршалинг означает, что маршалированная объектная ссылка может быть демаршалирована нуль и более раз без требования дополнительных вызовов CoMarshalInterface. Подробности табличного маршалинга будут описаны далее в этой главе.

Чтобы разрешить маршалинг интерфейсных указателей на различные носители, функция CoMarshalInterface преобразует интерфейсный указатель в последовательную форму через интерфейс типа IStream , предоставляемый вызывающим объектом. Интерфейс IStream моделирует произвольное устройство ввода-вывода и выставляет методы Read и Write . Функция CoMarshalInterface просто вызывает метод Write на предоставленный вызывающим объектом интерфейс типа IStream , не интересуясь тем, куда эти фактические байты будут записаны. Вызывающие объекты могут получить обертку IStream на необработанную (raw ) память, вызвав API- функцию CreateStreamOnHGlobal :

HRESULT CreateStreamOnHGlobal(

[in] HGLOBAL hglobal,

// pass null to autoalloc

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

[in] BOOL bFreeMemoryOnRelease,

[out] IStream **ppStm);

С использованием семантики IStream следующий фрагмент кода:

void UseRawMemoryToPrintString(void)

{

void *pv = 0;

// alloc memory

// выделяем память

pv = malloc(13);

if (pv != 0) {

// write a string to the underlying memory

// пишем строку в основную память

memcpy(pv, «Hello, World», 13);

printf((const char*)pv);

// free all resources

// освобождаем все ресурсы free (pv);

}

}

эквивалентен такому фрагменту кода, использующему интерфейс IStream вместо memcpy:

void UseStreamToPrintString(void)

{

IStream *pStm = 0;

// alloc memory and wrap behind an IStream interface

// выделяем память и затем заворачиваем ее в интерфейс

IStream HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStm);

if (SUCCEEDED(hr)) {

// write a string to the underlying memory

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

hr = pStm->Write(«Hello. World», 13, 0);

assert (SUCCEEDED (hr));

// suck out the memory

// извлекаем память

HGLOBAL hglobal = 0;

hr == GetHglobalFromStream(pStm, &hglobal);

assert(SUCCEEDED(hr));

printf((const char*)GlobalLock(hglobal));

// free all resources

// освобождаем все ресурсы

GlobalUnlock(hglobal); pStm->Release();

}

}

API-функция GetHGlobalFromStream позволяет вызывающему объекту получать дескриптор (handle ) памяти, выделенной функцией CreateStreamOnHGlobal. Использование HGLOBAL

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

0

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

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