Поделиться через


Программирование с использованием CComBSTR

Класс CComBSTR библиотеки ATL предоставляет программу-оболочку для типа данных BSTR.При CComBSTR эффективный инструмент, существует несколько ситуаций, требующих предосторежения.

  • Проблемы преобразования

  • Проблемы областей

  • Явное освобождение объект CComBSTR

  • Использование объектов CComBSTR в циклах

  • Проблемы утечки памяти

Проблемы преобразования

Хотя несколько методов CComBSTR автоматически преобразуют зашнуруйте аргумент ANSI в Юникод, методы всегда будет возвращать строки формата Юникода.Для преобразования строки вывода обратно в ANSI, используйте класс преобразования библиотеки ATL.Дополнительные сведения о классах преобразования библиотеки ATL см. в разделе Макросы преобразования строки библиотеки ATL и MFC.

bdyd6xz6.collapse_all(ru-ru,VS.110).gifПример

// 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 следует использовать широкие символьной строки.Это уменьшит ненужные преобразования.

bdyd6xz6.collapse_all(ru-ru,VS.110).gifПример

// 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, то это может привести к возникновению проблем, когда указатель будет ссылаться на память, которая уже была освобождена.В подобных случаях можно использовать метод Копировать, как показано ниже.

bdyd6xz6.collapse_all(ru-ru,VS.110).gifПример

// 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 недопустим.

bdyd6xz6.collapse_all(ru-ru,VS.110).gifПример

// 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 обеспечивает более высокую производительность.

bdyd6xz6.collapse_all(ru-ru,VS.110).gifПример

// 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].

См. также

Ссылки

Класс CStringT

wstring

Другие ресурсы

Основные понятия библиотеки ATL

Макросы преобразования строк