Сущность технологии СОМ. Библиотека программиста

ОглавлениеДобавить в закладки К обложке

CoMarshalInterface принимает на входе интерфейсный указатель и записывает преобразованное в последовательную форму представление указателя в предоставленный вызывающим объектом байтовый поток. Этот байтовый поток может затем быть передан в другой апартамент, где API-функция CoUnmarshalInterface использует байтовый поток для возвращения интерфейсного указателя, который семантически эквивалентен исходному объекту, и к которому можно легально обращаться в апартаменте, выполняющем вызов функции CoUnmarshalInterface. При вызове CoMarshalInterface вызывающий объект должен указать, насколько далеко может располагаться импортирующий апартамент. В СОМ определен список рекомендуемых расстояний:

typedef enum tagMSHCTX

{

MSHCTX_INPROC = 4,

// in-process/same host

// внутрипроцессный/тот же хост

MSHCTX_LOCAL = 0,

// out-of-process/same host

// внепроцессный/тот же хост

MSHCTX_NOSHAREDMEM = 1,

// 16/32 bit/same host

// 16/32-битный/тот же хост

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:


Логин
Пароль
Запомнить меня