Сущность технологии СОМ. Библиотека программиста | страница 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 в качестве строки: