Чтение онлайн

на главную - закладки

Жанры

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

// convert a variant to a designated type

// преобразуем вариант к указанному типу (с явным указанием кода локализации)

HRESULT VariantChangeTypeEx(VARIANTARG * plhs, VARIANTARG * prhs, LCID lcid, USHORT wFlags, VARTYPE vtlhs);

Эти функции значительно упрощают управление VARIANT'ами. Чтобы понять, как используются эти API-функции, рассмотрим метод, принимающий VARIANT в качестве [in]-параметра:

HRESULT UseIt([in] VARIANT var);

Следующий

фрагмент кода демонстрирует, как передать в этот метод целое число:

VARIANT var;

VariantInit(&var);

// initialize VARIANT

// инициализируем VARIANT

V_VT(&var) = VT_I4;

// set discriminator

// устанавливаем дискриминатор

V_I4(&var) = 100;

// set union

// устанавливаем объединение

HRESULT hr = pItf->UseIt(var);

// use VARIANT

// используем VARIANT

VariantClear(&var);

// free any resources in VARIANT

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

Отметим, что этот фрагмент кода использует макросы стандартного аксессора (accessor) для доступа к элементам данных VARIANT. Две следующие строки

V_VT(&var) = VT_I4;

V_I4(&var) = 100;

эквивалентны коду, который обращается к самим элементам данных:

var.vt = VT_I4;

var.lVal = 100;

Первый вариант предпочтительнее, так как он может компилироваться на С-трансляторах, которые не поддерживают неименованных объединений.

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

STDMETHODIMP MyClass::UseIt( /*[in] */ VARIANT var)

{

// declare and init a second VARIANT

// объявляем и инициализируем второй VARIANT

VARIANT var2;

VariantInit(&var2);

// convert var to a BSTR and store it in var2

// преобразуем переменную в BSTR и заносим ее в var2

HRESULT hr = VariantChangeType(&var2, &var, 0, VT_BSTR);

// use the string

// используем строку

if (SUCCEEDED(hr))

{

ustrcpy(m_szSomeDataMember, SAFEBSTR(V_BSTR(&var2)));

// free any resources held by var2

// освобождаем все ресурсы, поддерживаемые var2

VariantClear(&var2);

}

return hr;

}

Отметим, что API-процедура VariantChangeType способна осуществлять сложное преобразование любого переданного клиентом типа из VARIANT в нужный тип (в данном случае BSTR).

Один из последних типов данных, который вызывает дискуссию, – это интерфейс СОМ. Интерфейсы СОМ могут быть переданы в качестве параметров метода одним из двух способов. Если тип интерфейсного указателя известен на этапе проектирования, то тип интерфейса может быть объявлен статически:

HRESULT GetObject([out] IDog **ppDog);

Если

же тип на этапе проектирования неизвестен, то разработчик интерфейса может дать пользователю возможность задать тип на этапе выполнения. Для поддержки динамически типизируемых интерфейсов в IDL имеется атрибут [iid_is]:

HRESULT GetObject([in] REFIID riid, [out, iid_is(riid)] IUnknown **ppUnk);

Хотя эта форма будет работать вполне хорошо, следующий вариант предпочтительнее из-за его подобия с QueryInterface:

HRESULT GetObject([in] REFIID riid, [out, iid_is(riid)] void **ppv);

Атрибут [iid_is] можно использовать как с параметрами [in], так и [out] для типов IUnknown * или void *. Для того чтобы использовать параметр интерфейса с динамически типизируемым типом, необходимо просто установить IID указателя требуемого типа:

IDog *pDog = 0; HRESULT hr = pItf->GetObject(IID_IDog, (void**)&pDog);

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

STDMETHODIMP Class::GetObject(REFIID riid, void **ppv)

{

extern IUnknown * g_pUnkTheDog;

return g_pUnkTheDog->QueryInterface(riid, ppv);

}

Для уменьшения количества дополнительных вызовов методов между клиентом и объектом указатели интерфейса с динамически типизируемым типом должны всегда использоваться вместо указателей интерфейса со статически типизируемым типом IUnknown.

Атрибуты и свойства

Иногда бывает полезно показать, что объект имеет некие открытые свойства, которые могут быть доступны и/или которые можно модифицировать через СОМ-интерфейс. СОМ IDL позволяет аннотировать методы интерфейса с тем, чтобы данный метод либо модифицировал, либо читал именованный атрибут объекта. Рассмотрим такое определение интерфейса:

[ object, uuid(0BB3DAE1-11F4-11d1-8C84-0080C73925BA) ]

interface ICollie : IDog

{

// Age is a read-only property

// Age (возраст) – это свойство только для чтения

[propget] HRESULT Age([out, retval] long *pVal);

// HairCount is a read/write property

// HairCount (счетчик волос) – свойство для чтения/записи

[propget] HRESULT HairCount([out, retval] long *pVal);

[propput] HRESULT HairCount([in] long val);

// CurrentThought is a write-only property

// CurrentThought (текущая мысль) – свойство только для записи

[propput] HRESULT CurrentThought([in] BSTR val);

Поделиться:
Популярные книги

Семья. Измена. Развод

Высоцкая Мария Николаевна
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Семья. Измена. Развод

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Искушение генерала драконов

Лунёва Мария
2. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Искушение генерала драконов

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Камень Книга одиннадцатая

Минин Станислав
11. Камень
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Камень Книга одиннадцатая

Никто и звать никак

Ром Полина
Фантастика:
фэнтези
7.18
рейтинг книги
Никто и звать никак

Возвышение Меркурия. Книга 14

Кронос Александр
14. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 14

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Пограничная река. (Тетралогия)

Каменистый Артем
Пограничная река
Фантастика:
фэнтези
боевая фантастика
9.13
рейтинг книги
Пограничная река. (Тетралогия)

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Сумеречный Стрелок 2

Карелин Сергей Витальевич
2. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 2

Сумеречный Стрелок 10

Карелин Сергей Витальевич
10. Сумеречный стрелок
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Сумеречный Стрелок 10