ATL和MFC字符串翻译宏
讨论的字符串翻译宏此处为ATL和MFC有效。有关MFC字符串转换的更多信息,请参见 TN059:使用MFC MBCS/Unicode翻译宏 和 MFC宏和Globals。
ATL 7.0字符串转换选件类和宏
ATL 3.0字符串翻译宏
ATL 7.0字符串转换选件类和宏
ATL 7.0引入了一些新转换选件类和宏,提供在现有宏的重大改进。
新的字符串转换选件类和宏的名称采用形式:
CSourceType2[C]DestinationType[EX]
其中:
SourceType 和 DestinationType 在下表中所述。
[C]存在,则目标类型必须是常数时。
[EX] 存在,则必须指定缓冲区的初始大小用作模板参数时。
SourceType/DestinationType
说明
A
ANSI字符字符串。
W
Unicode字符串。
T
泛型字符字符串(等效于W,当_UNICODE定义,等效于否则为)。
OLE
OLE字符字符串(等效于W)。
例如,将Unicode字符串转换为泛型字符串,而不必更改已转换的字符串,使用 CW2CT。
如果知道该转换的字符串不能大于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,指定代码页作为第二个参数传递给构造函数。选件类。
安全说明 |
---|
在通过之前检查字符串的长度。这些宏避免潜在的缓冲区溢出问题。堆栈是还可以捕获具有筛选和除外)的异常。 |
具有较旧的字符串翻译宏和新的字符串转换选件类之间的几个重要的差异:
旧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个字符。如果需要特定转换"将缓冲区大小,请使用宏的预发布,并指定缓冲区大小用作模板参数。
// 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);
在宏名,源字符串类型在左侧(例如,)和目标字符串类型右边(例如,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 |
当目标类型是 BSTR时,使用_alloca,目标字符串创建,但。使用_alloca 分配内存,堆栈,因此,当函数返回时,会自动清理它。默认情况下此宏一次只转换到500KB。
在使用ATL字符串翻译宏时,请在您的函数开头指定 USES_CONVERSION 宏以避免编译器错误。例如:
void StringFunc(LPSTR lpsz)
{
USES_CONVERSION;
LPWSTR x = A2W(lpsz);
// Do something with x
wprintf_s(L"x is %s", x);
}
要求
Header file: AtlBase.h,AtlConv.h (声明在AtlConv.h)