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




Следующие два флага можно использовать в сочетании с вышеприведенными тегами, чтобы указать, что данный вариант (variant) содержит ссылку или массив данного типа:

VT_ARRAY Указывает, что вариант содержит массив SAFEARRAY

VT_BYREF Указывает, что вариант является ссылкой

СОМ предлагает несколько API-функций для управления VARIANT:


// initialize a variant to empty

// обнуляем вариант

void VariantInit(VARIANTARG * pvarg);

// release any resources held in a variant

// освобождаем все ресурсы, используемые в варианте

HRESULT VariantClear(VARIANTARG * pvarg);

// deep-copy one variant to another

// полностью копируем один вариант в другой

HRESULT VariantCopy(VARIANTARG * plhs, VARIANTARG * prhs);

// dereference and deep-copy one variant into another

// разыменовываем и полностью копируем один вариант в другой

HRESULT VariantCopyInd(VARIANT * plhs, VARIANTARG * prhs);

// convert a variant to a designated type

// преобразуем вариант к указанному типу

HRESULT VariantChangeType(VARIANTARG * plhs, VARIANTARG * prhs, USHORT wFlags, VARTYPE vtlhs);

// 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 в качестве строки: