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

GetWindowText(hwnd, szEditText, 1024);

// use _UNCC shim class to convert if necessary

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

// если необходимо

return IIDFromString(_UNCC(szEditText), &riid);

}

Заметим, что не требуется никакой условной компиляции. Если код скомпилирован с версией 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»));

// invoke method

// вызываем метод HRESULT hr = p->SetString(bstr);

// free BSTR

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

Промежуточный класс для работы с BSTR, _UBSTR, включен в заголовочный файл ustring.h:

// from ustring.h (book-specific header file)

// из ustring.h (специфический для данной книги заголовочный файл)

class _UBSTR

{

BSTR m_bstr;

public:

_UBSTR(const char *psz) : m_bstr(SysAllocStringLen(0, strlen(psz)))

{

mbstowcs(m_bstr, psz, INT_MAX);

}

_UBSTR(const wchar_t *pwsz) : m_bstr(SysAllocString(pwsz))

{

}

operator BSTR (void) const

{ return m_bstr; }

~_UBSTR(void)

{ SysFreeString(m_bstr); }

};

При наличии такого промежуточного класса предыдущий фрагмент кода значительно упростится:

// invoke method

// вызываем метод

HRESULT hr = p->SetString(_UBSTR(OLESTR(«Hello»)));

Заметим, что в промежуточном классе UBSTR могут быть в равной степени использованы строки типов char и wchar_t.

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

HRESULT GetString([out, retval] BSTR *pbstr);

При реализации метода потребуется создать новую BSTR-строку для возврата вызывающему объекту:

STDMETHODIMP MyClass::GetString(BSTR *pbstr)

{

*pbstr = SysAllocString(OLESTR(«Coodbye!»)) ;

return S_OK;

}

Теперь вызывающий объект должен освободить строку сразу после того, как она скопирована в управляемый приложением строковый буфер:

extern OLECHAR g_wsz[];

BSTR bstr = 0;

HRESULT hr = p->GetString(&bstr);

if (SUCCEEDED(hr))

{

wcscpy(g_wsz, bstr); SysFreeString(bstr);

}

Тут нужно рассмотреть еще один важный аспект BSTR. В качестве BSTR можно передать нулевой указатель, чтобы указать на пустую строку. Это означает, что предыдущий фрагмент кода не совсем корректен. Вызов wcscpy:

wcscpy(g_wsz, bstr);

должен быть защищен от возможных нулевых указателей:

wcscpy (g_wsz, bstr ? bstr : OLESTR(""));

Для упрощения использования BSTR в заголовочном файле ustring.h содержится простая встраиваемая функция:

intline OLECHAR *SAFEBSTR(BSTR b)

{

return b ? b : OLESTR("");

}

Разрешение использовать нулевые указатели в качестве BSTR делает тип данных более эффективным с точки зрения использования памяти, хотя и приходится засорять код этими простыми проверками.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных