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


ATL and MFC String Conversion Macros

Рассматриваемые здесь макросы преобразования строк можно использовать как для ATL, так и для MFC. Дополнительные сведения о преобразовании строки MFC см. в разделах TN059: использование макросов MFC для преобразования между Юникодом и многобайтовой кодировкой и Макросы MFC и глобальные функции.

  • Классы и макросы преобразования строк в ATL 7.0

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

Классы и макросы преобразования строк в ATL 7.0

ATL 7.0 представляет несколько новых классов и макросов преобразования, которые работают значительно лучше имеющихся макросов.

Имена новых классов и макросов преобразования строк имеют вид:

Cисходный_тип2[C]конечный_тип[EX]

Здесь:

  • значения исходный_тип и конечный_тип описаны в следующей таблице.

  • [C] присутствует, если конечный тип должен быть константой.

  • [EX] присутствует, если начальный размер буфера должен быть указан как аргумент шаблона.

    Значение "исходный_тип"/"конечный_тип"

    Описание

    A

    Строка символов ANSI.

    W

    Строка символов Юникод.

    T

    Строка универсальных символов (эквивалентна W при определенном _UNICODE, в противном случае эквивалентна A).

    OLE

    Строка символов OLE (эквивалентна W).

Например, чтобы выполнить преобразование из строки Юникода в универсальную строку без изменения преобразуемой строки, используйте CW2CT.

Предупреждение

Некоторые перестановки указанного выше шаблона не поддерживаются.CA2CW и CW2CA (а также CA2CWEX и CW2CAEX) не поддерживаются.Для преобразования строки символов OLE поддерживаются только COLE2T и CT2OLE (а также COLE2CT, COLE2TEX, COLE2CTEX, CT2COLE, CT2OLEEX и CT2COLEEX).Дополнительные сведения см. в atlconv.h.

Если известно, что длина преобразуемой строки не превышает 64 символов, для экономии места в стеке можно использовать версию EX, такую как CW2CTEX<64>.

Примечание

Для преобразования из строк BSTR и в них рекомендуется использовать класс CComBSTR.Для преобразования в BSTR передайте имеющуюся строку в конструктор CComBSTR.Для преобразования из BSTR используйте COLE2[C]DestinationType[EX], например COLE2T.

Новые классы преобразования (CA2AEX, CA2WEX, CW2AEX и CW2WEX), которым требуется буфер, используют статический буфер фиксированного размера для хранения результата преобразования. Если результат слишком большой для помещения в статический буфер, класс выделяет память с помощью malloc, освобождая ее, когда объект выходит за пределы области. Благодаря этому новые классы, в отличие от старых макросов текстового преобразования, можно безопасно использовать в циклах, а также они не приводят к переполнению стека.

Макросы преобразования, представленные в ATL 7.0, оптимизированы для поддержки входных строк NULL. Эти макросы возвращают NULL, если входной параметр имеет значение NULL, без выделения какой-либо памяти.

По умолчанию классы и макросы преобразования ATL используют для преобразования кодовую страницу ANSI текущего потока. Если вы хотите переопределить такой режим работы для отдельного преобразования с использованием макросов, основанных на классах CA2WEX или CW2AEX, укажите кодовую страницу в качестве второго параметра конструктора для такого класса.

Примечание о безопасностиПримечание по безопасности

Проверьте длину строк, прежде чем передавать их в эти макросы, чтобы предотвратить потенциальные проблемы с переполнением буфера.Переполнения стека являются исключениями, которые также можно перехватить с помощью try/except.

Существует несколько важных различий между старыми макросами преобразования строк и новыми классами преобразования строк.

Старые макросы преобразования строк в ATL 3.0

Новые классы преобразования строк в ATL 7.0

Выделение памяти в стеке.

Использует память стека для небольших строк. Использует кучу, если стек имеет недостаточный размер.

Строка освобождается после выполнения выхода из функции.

Строка освобождается, когда переменная выходит за пределы области.

Не может использоваться в обработчиках исключений.

Может использоваться в обработчиках исключений.

Не подходит для использования в циклах. Используемый объем памяти увеличивается до выполнения выхода из функции.

Поддерживает использование в циклах. Область цикла гарантирует освобождение памяти на каждой итерации.

Плохо подходит для больших строк. Пространство стека ограничено.

Полностью поддерживает большие строки. Строки размещаются в куче.

Обычно требует определить USES_CONVERSION.

Никогда не требует определить USES_CONVERSION.

Значение OLE зависит от определения OLE2ANSI.

OLE всегда эквивалентно W.

Пример

Код

//Example 1 
// Convert LPCWSTR to LPCSTR. 
void ExampleFunction1(LPCWSTR pszW)
{
   // Create an instance of CW2A, called pszA, 
   // and initialize it with pszW.
   CW2A pszA(pszW);
   // pszA works like an LPCSTR, and can be used thus:
   ExampleFunctionA(pszA);  
   // Note: pszA will become invalid when it goes out of scope.
}

// Example 2 
// Use a temporary instance of CW2A. 
void ExampleFunction2(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A, 
   // and initialize it with pszW.
   ExampleFunctionA(CW2A(pszW));
   // Note: the temporary instance becomes invalid  
   // after the execution of the statement above.
}

// Example 3 
// Incorrect use of conversion macros. 
void ExampleFunction3(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A, 
   // save a pointer to it and then delete 
   // the temportary instance.
   LPCSTR pszA = CW2A(pszW);
   // The pszA in the following line is an invalid pointer, 
   // as the instance of CW2A has gone out of scope.
   ExampleFunctionA(pszA);
}

Предупреждение относительно временных экземпляров класса

Следует подчеркнуть, что следующий код нельзя назвать удачным:

LPCTSTR szr = CA2T(szReplaceFile);

При использовании макросов ATL 3.0 можно было применить:

LPCTSTR szr = A2T(szReplaceFile);   

так как выделенная функциями преобразования память не была бы освобождена до выхода из текущей функции. С новыми классами этот код не работает.

Этот код:

LPCTSTR szr = CA2T(szReplaceFile);   

эквивалентен следующему:

LPCTSTR szr;
{
   CA2T temp(szReplaceFile);
   szr = temp.operator LPTSTR();
}   

Поскольку память, выделяемая временным объектом и возвращаемая из оператора приведения, уничтожается при уничтожении временного объекта, использование значения в szr приведет к нежелательным результатам.

Вместо этого используйте следующий код:

CA2T szr(szReplaceFile);   

Оператор приведения заставляет объект CA2T выглядеть как LPCTSTR.

Расширенные возможности использования

Размер статического буфера по умолчанию составляет 128 символов. Если этот размер нужно изменить для определенного преобразования, используйте версию EX макроса и укажите размер буфера в качестве аргумента шаблона.

// Example 4 
// Changing the size of the buffer. 
void ExampleFunction4(LPCWSTR pszW)
{
   // Use a 16-character buffer.
   ExampleFunctionA(CW2AEX<16>(pszW));
}

Ниже приведен пример указания кодовой страницы в качестве второго параметра конструктора для класса.

// Example 5 
// Specifying the code page. 
void ExampleFunction5(LPCWSTR pszW)
{
   // Convert to the Macintosh code page
   ExampleFunctionA(CW2A(pszW, CP_MACCP));
}

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

Исходные макросы текстового преобразования се еще доступны и перечислены в следующей таблице.

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

A2BSTR

OLE2A

T2A

W2A

A2COLE

OLE2BSTR

T2BSTR

W2BSTR

A2CT

OLE2CA

T2CA (Нерекомендуемый. Вместо него следует использовать T2CA_EX или CT2CA.)

W2CA

A2CW

OLE2CT

T2COLE

W2COLE

A2OLE

OLE2CW

T2CW

W2CT

A2T

OLE2T

T2OLE

W2OLE

A2W

OLE2W

T2W

W2T

Синтаксис для использования этих макросов имеет следующий вид:

MACRONAME( string_address )

Например:

A2W(lpa);

В именах макросов тип исходной строки расположен слева (например, A), а конечный тип строки — справа (например, W). A означает LPSTR, OLE означает LPOLESTR, T означает LPTSTR, а W означает LPWSTR.

Если в имени макроса присутствует C, этот макрос выполняет преобразование в строку const. Например, W2CA преобразует LPWSTR в LPCSTR.

Таким образом, A2W преобразует LPSTR в LPWSTR, OLE2T преобразует LPOLESTR в LPTSTR и т. д.

Режим работы макроса преобразования строки ATL зависит от действующей директивы компилятора (если она есть). Если исходный и конечный типы совпадают, преобразование не выполняется. Директивы компилятора изменяют T и OLE следующим образом:

Действующая директива компилятора

T становится

OLE становится

Нет

A

W

_UNICODE

W

W

OLE2ANSI

A

A

_UNICODE и OLE2ANSI

W

A

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

При использовании макроса преобразования строк ATL укажите макрос USES_CONVERSION в начале своей функции, чтобы предотвратить ошибки компилятора. Например:

void StringFunc(LPSTR lpsz)
{
   USES_CONVERSION;

   LPWSTR x = A2W(lpsz);
   // Do something with x
   wprintf_s(L"x is %s", x);
}

Требования

Файл заголовка: AtlBase.h, AtlConv.h (объявлен в AtlConv.h).

См. также

Ссылки

DEVMODE and TEXTMETRIC String Conversion Macros

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

Макросы ATL