ATL 和 MFC 字符转换宏
ATL3.0
Ø ATL3.0中的W2T ,T2W等一系列宏很方便,但一定要小心,它们从栈上分配内存,直到调用它的函数返回前,该内存不会被释放,如果在一个循环中,这类宏被你反复调用几万次时,你将不可避免地产生stack overflow 。解决的方法是,将用到该宏的语句独立封装成一个函数,这样就可以无限次调用了。
Ø ATL3.0的主要宏如下:
Ø 使用方法如下.
#include <atlconv.h>
void StringFunc(LPSTR lpsz)
{
USES_CONVERSION;
LPWSTR x = A2W(lpsz);
// Do something with x
}
Ø 这些宏的名字有一它的意义, 被转换的字符在左边(如: A) 转换后的字符在后边(如:W),2表示To ,A是LPSTR字符,, OLE 是LPOLESTR字符, T 是 LPTSTR字符, W 是 LPWSTR字符。如果宏的名字中含有C,表示该宏将会转换成一个Const string,例如, W2CA 将LPWSTR 转换成LPCSTR., A2W 将 LPSTR 转换成 LPWSTR, OLE2T 将LPOLESTR t转换成 LPTSTR……
Ø ATL宏的行为取决于编译器指令生成效果,如果源字符和目的字符类型相同,就不会发生转换动作,编译器在预编译过程中将会将宏名种的T和OLE参照如下表进行转换。
是否存在下列预编译宏 |
| T 成为 | OLE成为 |
没有定义 | A | W | |
定义了_UNICODE | W | W | |
定义了OLE2ANSI | A | A | |
定义了_UNICODE 和OLE2ANSI | W | A |
ATL7.0
Ø ATL7.0增加了几种新的宏和类,对已有的宏做了很大的该进.
Ø ATL7.0宏名形如如下形式 --- C(源字符类型)2[C](目的字符类型) [EX]
其中:
· 源字符类型和目的字符类型参照下表。
· 如果目的字符类型要求是常量,则需要 [C]。
· 如果需要以参数形式指定目的字符内存初始化大小,则需要[EX]。
源字符类型/目的字符类型 | 说 明 |
A | ANSI character string. |
W | Unicode character string. |
T | Generic character string (equivalent to W when _UNICODE is defined, equivalent to A otherwise). |
OLE | OLE character string (equivalent to W). |
例如,将一个Unicode string 转换成 普通string 而不改变源string ,可以用CW2CT。如果已经知道转换后的字符不会超过64个字符,可以选择含有EX的宏,并将大小限制以参数形式指定如:CW2CTEX<64>。
Ø ATL7.0新增的转换类: (CA2AEX, CA2WEX, CW2AEX, and CW2WEX) ,他们需要修正的静态存储区来保结果,如果转换后的字符过大,超出了静态存储区内存大小,这些类会自动释放内存,保证了安全性,避免了ATL3.0中宏在循环过程中会将栈占满。7.0对空字符的输入做了处理,如果输入为空字符,返回空,不会分配内存。
Ø 部分代码如下
#define COLE2T CW2T #define COLE2TEX CW2TEX
#define COLE2CT CW2CT #define COLE2CTEX CW2CTEX
#define CT2OLE CT2W #define CT2OLEEX CT2WEX
#define CT2COLE CT2CW #define CT2COLEEX CT2CWEX
class CW2WEX, class CA2AEX
typedef CW2WEX<> CW2W typedef CA2AEX<> CA2A
class CA2CAEX class CW2CWEX
typedef CA2CAEX<> CA2CA typedef CW2CWEX<> CW2CW
class CA2WEX class CW2AEX
typedef CA2WEX<> CA2W typedef CW2AEX<> CW2A
Ø ATL3.0字符转换宏和ATL7.0字符转换宏和转换类的主要区别如下:
ATL 3.0 字符转换宏 | ATL 7.0字符转换类 |
在栈上分配内存 | 小字符在栈上分配,大字符在堆上分配 |
函数退出后,转换后的字符被释放 | 当超出一定的使用限制时,字符才被释放 |
没有意外情况处理 | 有意外情况处理 |
不适合在循环中使用 | 可以在循环中使用 |
栈空间有限, 不适合大字符 | 字符大小没有限制,可以在堆上分配内存 |
需要定义USES_CONVERSION宏 | 不需要定义USES_CONVERSION宏 |
OLE的类型取决于OLE2ANSI宏的定义 | OLE类型总是和 W类型相同 |