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



}


Заметим, что не требуется никакой условной компиляции. Если код скомпилирован с версией Win32 с поддержкой Unicode, то класс _UNCC просто пропустит исходный буфер через свой оператор приведения типа. Если же код компилируется с версией Win32, не поддерживающей Unicode, то класс _UNCC выделит буфер и преобразует строку в Unicode. Затем деструктор _UNCC освободит буфер, когда операция будет выполнена полностью[3].

Следует обсудить еще один дополнительный тип данных, связанный с текстом, – BSTR. Строковый тип BSTR нужно применять во всех интерфейсах, которые предполагается использовать из языков Visual Basic или Java. Строки BSTR являются OLECHAR-строками с префиксом длины (length-prefix) в начале строки и нулем в ее конце. Префикс длины показывает число байт, содержащихся в строке (исключая завершающий нуль) и записан в форме четырехбайтового целого числа, непосредственно предшествующего первому символу строки. Рисунок 2.7 демонстрирует BSTR на примере строки «Hi». Чтобы позволить методам свободно возвращать строки BSTR без заботы о выделении памяти, все BSTR размещены с помощью распределителя памяти, управляемого СОМ. В СОМ предусмотрено несколько API-функций для управления BSTR:



// from oleauto.h

// allocate and initialize a BSTR

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

BSTR SysAllocString(const OLECHAR *psz);

BSTR SysAllocStringLen(const OLECHAR *psz, UINT cch);

// reallocate and initialize a BSTR

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

INT SysReAllocString(BSTR *pbstr, const OLECHAR *psz);

INT SysReAllocStringLen(BSTR *pbstr, const OLECHAR * psz, UINT cch);

// free a BSTR

// освобождаем BSTR void SysFreeString(BSTR bstr);

// peek at length-prefix as characters or bytes

// считываем префикс длины как число символов или байт

UINT SysStringLen(BSTR bstr);

UINT SysStringByteLen(BSTR bstr);


При пересылке строк методу в качестве параметров типа [in] вызывающий объект должен заботиться о том, чтобы вызвать SysAllocString прежде, чем запускать сам метод, и чтобы вызвать SysFreeString после того, как метод закончил работу. Рассмотрим следующее определение метода:


HRESULT SetString([in] BSTR bstr);


Пусть в вызывающей программе уже имеется строка, совместимая с OLECHAR, тогда для того, чтобы преобразовать строку в BSTR до вызова метода, необходимо следующее:


// convert raw OLECHAR string to a BSTR

// преобразовываем «сырую» строку OLECHAR в строку BSTR

BSTR bstr = SysAllocString(OLESTR(«Hello»));