ATL and MFC String Conversion Macros

ATL 7.0介绍了一些新的转换类和宏,为现有的宏提供了重要的改进。
新的字符串转换类和名称宏的形式是:C 源类型 2[C] 目标类型[EX]
其中:
•源类型和目标类型描述如下表.
• [C]是目标类型必须是只读的.
•[EX]是缓冲器的初始大小必须被指定为一个模板参数。

源类型/目标类型  描述
ANSI字符串
Unicode字符串
T  通用字符串(如果定义了_UNICODE)则等同于W,否则等同于A
OLE  OLE字符串(等同于W)

例如,从一个Unicode字符串转换为普通字符串不改变转换后的字符串,使用CW2CT。
小心:
上面的一些组合是不支持的。CA2CW和CW2CA(以及CA2CWEX和CW2CAEX)是不支持的。
对于OLE字符串的转换,只支持COLE2T和CT2OLE(以及COLE2CT,COLE2TEX,COLE2CTEX,CT2COLE,CT2OLEEX和CT2COLEEX)。更多细节,参考atlconv.h.
注意:

对于BSTR字符串的转换操作推荐使用CComBSTR类,转换为BSTR时将现有的字符串传入CComBSTR的构造函数,从BSTR转换,使用COLE2[C] 目标类型[EX],比如COLE2T。
新的转换类要求用一个固定大小的静态缓存区来存储转换结果。如果结果太大而不适合静态缓存区,类将使用malloc来分配内存,并在对象超出范围之后释放内存。不像较早的文本转换宏,以上特性保证了这些类在循环中的安全使用,避免了栈溢出。
默认情况下,ATL转换类和转换宏使用当前线程的ANSI代码页转换。如果有特殊转换需要覆盖默认行为,可以使用基于类CA2WEX 或 CW2AEX的宏,在类的构造函数的第二个参数指定代码页。

安全提醒:
将字符串传入这些宏之前检查长度可以避免潜在的缓冲区溢出问题。堆栈溢出可以通过try/except抓取。

旧的字符串转换宏和新的字符串转换类之间的几个重要区别:

Old ATL 3.0 Conversion Macros New ATL 7.0 Conversion Classes
在栈上分配内存 小字符串在栈上,栈内存不足则使用堆
函数退出时释放字符串 变量超出范围时释放字符串
无异常处理  可以在异常处理中使用
不适合循环使用,内存增长直到函数退出  支持循环使用 循环范围确保内存被释放在每个迭代
不适合大的字符串,栈内存有限  支持大字符串,堆上分配内存
需要USES_CONVERSION  不再需要USES_CONVERSION
OLE的意义取决于OLE2ANSI的定义 . OLE始终等于W
示例代码:
//Example 1
// 将LPCWSTR 转为 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
// 使用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
// 转换宏的错误使用
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); //ERROR USE
   // 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);

使用ATL3.0宏,这是可以接受的使用方法:
LPCTSTR szr = A2T(szReplaceFile);   //A2T→ ATL 3.0
因为由转换函数申请的内存直到函数退出时才释放。同样的代码在新的(ATL 7.0)类中是不工作的。

为什么呢?
这行代码
 LPCTSTR szr = CA2T(szReplaceFile); 
实际上等价于
LPCTSTR szr;
{
   CA2T temp(szReplaceFile);
   szr = temp.operator LPTSTR();
}   
因为内存是由临时对象申请的、由类型转换操作符返回的,当对象销毁时它也销毁了,再使用szr的值结果将是未知的。替换代码是,
CA2T szr(szReplaceFile);   
这样,类型转换操作符(cast operator)生产了一个LPCTSTR.

高阶使用
默认的静态缓冲区大小是128个字符,如果需要改变缓冲区的大小,使用EX版本的宏,并以模板参数指定缓冲区的大小。

// Example 4
// 改变缓冲区的大小
void ExampleFunction4(LPCWSTR pszW)
{
   // 使用16个字符的缓冲区.
   ExampleFunctionA(CW2AEX<16>(pszW));
}

下面是一个通过类构造函数的第二个参数指定代码页大小的例子:
// Example 5
// 指定代码页.
void ExampleFunction5(LPCWSTR pszW)
{
   // Convert to the Macintosh code page
   ExampleFunctionA(CW2A(pszW, CP_MACCP));
}

ATL 3.0 字符串转换宏

原始文本转换宏仍然可用,列于下表:
ATL3.0字符串转换宏:
A2BSTR OLE2A  T2A  W2A 
A2COLE  OLE2BSTR  T2BSTR  W2BSTR 
A2CT  OLE2CA  T2CA W2CA 
A2CW  OLE2CT  T2COLE  W2COLE 
A2OLE  OLE2CW  T2CW  W2CT 
A2T  OLE2T  T2OLE  W2OLE 
A2W  OLE2W  T2W  W2T

其中T2CA (不推荐. 用 T2CA_EX 或 CT2CA 替换)
使用这些宏的语法:MACRO_NAME( string_address ) e.g.: A2W(lpa);
在宏名中,源字符串类型在左,目标字符串类型在右。
A表示LPSTR,OLE代表LPOLESTR,T代表LPTSTR,而W代表LPWSTR。
如果宏名中有‘C’,则表示转为const字符串。例如,W2CA将LPWSTR 转为 LPCSTR.
A2W 将LPSTR 转为 LPWSTR, OLE2T 将 LPOLESTR 转为 LPTSTR,等等.
ATL字符串转换宏的行为依赖于实际的编译指令,如果有的话。如果源类型和目的类型相同,则不作任何转换。

编译器指令对T和OLE的改变如下:

编译器指令 T变成 OLE变成
NONE  A   W
_UNICODE W W
OLE2ANSI A A
_UNICODE和OLE2ANSI W A

目标字符串使用_alloca创建,当目标类型为BSTR除外。使用_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);
}

要求
头文件:AtlBase.h, AtlConv.h (declared in AtlConv.h)
参见
参考DEVMODE and TEXTMETRIC String Conversion Macros 
其它资源ATL Macros

原文

时间: 2024-11-11 03:13:38

ATL and MFC String Conversion Macros的相关文章

Notice:Array to string conversion的问题

如果后台或者前端输出这样的提示: Notice: Array to string conversion 原因是:用 echo  来输出数组,当然会报错,数组应该用print , print_r , 或者 var_dump来打印: 如果你在前端的嵌套PHP代码,想将一个数组赋值给一个变量,像这样的: 1 <script> 2 var text = <?php echo $text;?>; //$text是一个数组的话,就会报错 3 </script> 4 5 解决方法:

VS2008中 ATL CLR MFC Win32 区别

ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用MFC,使用API函数编的程序.MFC.ATL和CLR是VC2005内置的3大库,涵盖了windows的各种开发方法和开发应用.当然关于C++开发的库不止这3个,不过这3个是微软推荐.从编程所处层次而言,WIN32为最底层,其次是MFC.然后是CLR.WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就是不用MFC,使用AP

ATL CLR MFC Win32 常规 的区别

ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用 MFC,使用API函数编的程序. MFC.ATL和CLR是VC2005内置的3大库,涵盖了windows的各种开发方法和开发应用.当然关于C++开发的库不止这3个,不过这3个是微 软推荐.从编程所处层次而言,WIN32为最底层,其次是MFC.然后是CLR. WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就是不用MFC,

Visual Studio中 ATL CLR MFC Win32 区别

ATL用于编写COM程序, CLR是.NET的公共语言运行库, MFC是指MFC类库,MFC程序是用这些类库做出的程序, WIN32常规就是不用MFC,使用API函数编的程序. MFC.ATL和CLR是VC2005内置的3大库,涵盖了windows的各种开发方法和开发应用.当然关于C++开发的库不止这3个,不过这3个是微软推荐.从编程所处层次而言,WIN32为最底层,其次是MFC.然后是CLR. WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就是不用MFC

BYTE TO HEX AND HEX TO BYTE STRING CONVERSION

I write a lot of ad-hoc protocol analysers using Python. Generally, I'm dealing with a byte stream that I want to output as a string of hex. Sometimes, I want to convert it back again. Eventually, I got round to putting the functions in a module so I

php,二维数组的输出出现了问题,提示:Notice: Array to string conversion

<?php $arr=array(array("111","222","333"),array("444","555","666")); print_r("{$arr[0][1]}"); ?> 这样就可以了,多维数组.以及下标不是简单数值的数组,都需要{}起来. 将数据传递到javascript中时同样适用

【转】MFC String处理

原文网址:http://www.cnblogs.com/lisuyun/p/3399232.html C/C++获取文件后缀名并且比较 以下这段是VC中过去文件后缀名的方法 1.CString GetSuffix(CString strFileName) {         return strFileName.Right(strFileName.GetLength()-strFileName.ReverseFind('.')-1); } 2.PathFindExtension 3.忽略大小写方

Convert CString to ANSI string in UNICODE projects

Convert CString to ANSI string in UNICODE projects Quick Answer: use an intermediate CStringA. Normally, this is not something that should be done. *It is technically unreliable, unless you can guarantee that the source CString to be converted does n

1.字符转换

1.将单字节Char转化为双字节的wchar_t的转换函数 wchar_t* c2w(const char *str){     int length = strlen(str)+1;     wchar_t *t = (wchar_t*)malloc(sizeof(wchar_t)*length);     memset(t,0,length*sizeof(wchar_t));     MultiByteToWideChar(CP_ACP,0,str,strlen(str),t,length)