ATL 7.0 introduces some of the new transformation classes and macros that provide important improvements to existing macros.
The new string conversion class and name macro form: C Source type 2[c] target type [EX]
which
• The source type and target type are described in the following table.
[c] is the target type must be read-only.
[ex] is the initial size of the buffer that must be specified as a template parameter.
Source Type/target type |
Describe |
A |
ANSI String |
W |
Unicode string |
T |
Universal string (if _UNICODE is defined) is equivalent to W, otherwise equivalent to a |
Ole |
OLE string (equivalent to W) |
For example, converting from a Unicode string to a normal string does not change the converted string, using CW2CT.
Be careful:
Some of the above combinations are not supported. CA2CW and CW2CA (as well as Ca2cwex and CW2CAEX) are not supported.
For the conversion of OLE strings, only cole2t and Ct2ole (as well as Cole2ct,cole2tex,cole2ctex,ct2cole,ct2oleex and Ct2coleex) are supported. For more details, refer to Atlconv.h.
Attention:
Conversion operations for BSTR strings are recommended for use with the CComBSTR class, when converted to a BSTR, the existing string is passed into the CComBSTR constructor, converted from a BSTR, using the COLE2[C] target type [EX], such as cole2t.
The new transformation class requires a fixed-size static buffer to store the conversion results. If the result is too large to fit in the static buffer, the class uses malloc to allocate memory and free memory after the object goes out of scope. Unlike earlier text conversion macros, the above features guarantee the safe use of these classes in loops and avoid stack overflows.
By default, the ATL conversion classes and transformation macros use the current thread's ANSI code page conversions. If a special conversion is required to override the default behavior, you can use a macro based on class Ca2wex or CW2AEX to specify the code page in the second parameter of the class's constructor.
Security Reminders:
Checking the length before passing a string to these macros avoids potential buffer overflow problems. Stack overflow can be crawled through try/except.
There are several important differences between the old string conversion macro and the new string conversion class:
Old ATL 3.0 Conversion Macros |
New ATL 7.0 Conversion Classes |
allocating memory on the stack |
Small strings on the stack, stack memory is not enough to use heap |
Releasing a string when the function exits |
Free string when variable is out of range |
No exception handling |
can be used in exception handling |
Not suitable for cyclic use, memory growth until function exits |
Supports cyclic use of loop range to ensure that memory is released at each iteration |
Not suitable for large strings, stack memory is limited |
Supports large strings and allocates memory on the heap |
Need uses_conversion |
No longer need uses_conversion |
The meaning of OLE depends on the definition of Ole2ansi. |
Ole always equals W |
Example code://Example 1//convert LPCWSTR to LPCSTR.voidExampleFunction1 (lpcwstr pszw) {//Create An instance of cw2a, called Psza,//and initialize it with PSZW.cw2a Psza (PSZW); //Psza works like a LPCSTR, and can be used thus:Examplefunctiona (Psza); //Note:psza would become invalid when it goes out of scope.}//Example 2//use a temporary instance of CW2AvoidExampleFunction2 (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 macrosvoidExampleFunction3 (lpcwstr pszw) {//Create A temporary instance of CW2A,//save a pointer to it and then delete//The temportary instance.LPCSTR Psza = cw2a (PSZW);//ERROR Use//the Psza in the following line was an invalid pointer,//As the instance of CW2A have gone out of scope.Examplefunctiona (Psza);}
A warning about temporary class instances:
It should be emphasized that the following code is the wrong code.
LPCTSTR SZR = ca2t (szreplacefile);
Using the ATL3.0 macro, this is an acceptable way to use:
LPCTSTR SZR = a2t (szreplacefile); A2t→atl 3.0
Because the memory requested by the conversion function is not released until the function exits. The same code is not working in the new (ATL 7.0) class.
Why is it?
This line of code
LPCTSTR SZR = ca2t (szreplacefile);
is actually equivalent to
LPCTSTR SZR;
{
CA2T temp (szreplacefile);
SZR = Temp.operator LPTSTR ();
}
Because memory is requested by a temporary object and returned by the type conversion operator, it is also destroyed when the object is destroyed, and the result of using the SZR value will be unknown. The replacement code is,
CA2T SZR (Szreplacefile);
In this way, the type conversion operator (cast operator) produces a LPCTSTR.
Advanced use
The default static buffer size is 128 characters, and if you need to change the size of the buffer, use the EX version of the macro and specify the size of the buffer with the template parameter.
//Example 4//change the size of the buffervoidExampleFunction4 (lpcwstr pszw) {//use a 16-character buffer.Examplefunctiona (cw2aex< ->(PSZW));} The following is an example of specifying a code page size through the second parameter of a class constructor://Example 5//Specifies the code page.voidExampleFunction5 (lpcwstr pszw) {//Convert to the Macintosh code pageExamplefunctiona (CW2A (PSZW, CP_MACCP));}
ATL 3.0 String Conversion macros
The original text conversion macros are still available, listed in the following table:
ATL3.0 String Conversion Macros:
A2BSTROLE2A T2A W2A
A2cole ole2bstr t2bstr W2bstr
A2CT OLE2CA T2CAW2CA
A2CW ole2ct t2cole W2cole
A2ole OLE2CW T2CW w2ct
A2T ole2t T2ole W2ole
a2w ole2w t2w w2t
where T2CA (not recommended). Replace with T2CA_EX or CT2CA
Syntax for using these macros: Macro_name (string_address) e.g.: a2w (LPA);
In the macro name, the source string type is left, and the target string type is on the right.
A means that Lpstr,ole represents lpolestr,t on behalf of LPTStr and W represents LPWSTR.
If there is ' C ' in the macro name, it is converted to a const string. For example, W2CA converts LPWSTR to LPCSTR.
A2W will lpstr to LPWStr, ole2t lpolestr to LPTSTR, and so on.
The behavior of an ATL string conversion macro depends on the actual compilation instructions, if any. If the source type and destination type are the same, no conversions are made.
The compiler directives change the T and OLE as follows:
Compiler directives |
T becomes |
OLE becomes |
NONE |
A |
W |
_unicode |
W |
W |
Ole2ansi |
A |
A |
_unicode and Ole2ansi |
W |
A |
The target string is created using _alloca, except when the target type is a BSTR. Use _alloca to allocate memory from the stack so that it is automatically freed when the function returns. By default, this macro can convert 500KB of content at a time.
Before using an ATL string to convert a macro, you need to specify uses_conversion at the beginning of the function to avoid compilation errors. For example:
void Stringfunc (LPSTR lpsz)
{
Uses_conversion;
LPWSTR x = a2w (lpsz);
Do something with X
wprintf_s (L "x is%s", x);
}
Requirements
Header files: AtlBase.h, AtlConv.h (declared in AtlConv.h)
See
Reference DEVMODE and textmetric String Conversion Macros
Other Resources ATL Macros
Original
ATL and MFC String Conversion Macros