Программирование с использованием CComBSTR (ATL)
Класс CComBSTR библиотеки ATL предоставляет программу-оболочку для типа данных BSTR. При CComBSTR эффективный инструмент, существует несколько ситуаций, требующих предосторежения.
Проблемы преобразования
Проблемы областей
Явное освобождение объект CComBSTR
Использование объектов CComBSTR в циклах
Проблемы утечки памяти
Проблемы преобразования
Хотя несколько методов CComBSTR автоматически преобразуют зашнуруйте аргумент ANSI в Юникод, методы всегда будет возвращать строки формата Юникода. Для преобразования строки вывода обратно в ANSI, используйте класс преобразования библиотеки ATL. Дополнительные сведения о классах преобразования библиотеки ATL см. в разделе Макросы преобразования строки библиотеки ATL и MFC.
Пример
// Declare a CComBSTR object. Although the argument is ANSI,
// the constructor converts it into UNICODE.
CComBSTR bstrMyString("Hello World");
// Convert the string into an ANSI string
CW2A szMyString(bstrMyString);
// Display the ANSI string
MessageBoxA(NULL, szMyString, "String Test", MB_OK);
Если используется строковый литерал, чтобы изменить объект CComBSTR следует использовать широкие символьной строки. Это уменьшит ненужные преобразования.
Пример
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Проблемы областей
Как и с любым хорошо- поступаемым классом, CComBSTR освободит его ресурсы, когда он переместится из области. Если функция возвращает указатель на строку CComBSTR, то это может привести к возникновению проблем, когда указатель будет ссылаться на память, которая уже была освобождена. В подобных случаях можно использовать метод Копировать, как показано ниже.
Пример
// The wrong way to do it
BSTR * MyBadFunction()
{
// Create the CComBSTR object
CComBSTR bstrString(L"Hello World");
// Convert the string to uppercase
HRESULT hr;
hr = bstrString.ToUpper();
// Return a pointer to the BSTR. ** Bad thing to do **
return &bstrString;
}
// The correct way to do it
HRESULT MyGoodFunction(/*[out]*/ BSTR* bstrStringPtr)
{
// Create the CComBSTR object
CComBSTR bstrString(L"Hello World");
// Convert the string to uppercase
HRESULT hr;
hr = bstrString.ToUpper();
if (hr != S_OK)
return hr;
// Return a copy of the string.
return bstrString.CopyTo(bstrStringPtr);
}
Явное освобождение объект CComBSTR
Возможно явно освобождать строку, содержащихся в объекте CComBSTR, прежде чем объект выходит за пределами области. Если строки освобождается, то объект CComBSTR недопустим.
Пример
// Declare a CComBSTR object
CComBSTR bstrMyString(L"Hello World");
// Free the string explicitly
::SysFreeString(bstrMyString);
// The string will be freed a second time
// when the CComBSTR object goes out of scope,
// which is invalid.
Использование объектов CComBSTR в циклах
По мере того, как класс CComBSTR выделяет буфер для выполнения различных операций, например оператор += или метод Добавление, не рекомендуется выполнить манипуляцию строки в плотного цикла. В этих случаях CStringT обеспечивает более высокую производительность.
Пример
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
Проблемы утечки памяти
Передача адрес, инициализированный CComBSTR функции в качестве параметра [out] вызовет утечку памяти.
В примере, приведенном ниже, протечена строка, выделенная для хранения строки "Initialized", если функция MyGoodFunction заменяет строки.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Во избежание утечки, вызовите метод Пусто на существующие объекты CComBSTR перед передачей адрес в качестве параметра [out].
Обратите внимание, что один и тот же код не вызвал утечку если параметр функции было [in, out].
См. также
Ссылки
Другие ресурсы
Основные понятия активной библиотеки шаблонных классов (ATL)