ATL and MFC String Conversion Macros
ATL 7.0介绍了一些新的转换类和宏,为现有的宏提供了重要的改进。
新的字符串转换类和名称宏的形式是:C 源类型 2[C] 目标类型[EX]
其中:
•源类型和目标类型描述如下表.
• [C]是目标类型必须是只读的.
•[EX]是缓冲器的初始大小必须被指定为一个模板参数。
源类型/目标类型 | 描述 |
A | ANSI字符串 |
W | 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<>(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
ATL and MFC String Conversion Macros的更多相关文章
- ATL、MFC、WTL CString 的今生前世(转载)
转载:https://www.cnblogs.com/tekkaman/archive/2011/04/20/2022650.html 上文分析了ATL.MFC CString的设计和实现,我们不禁会 ...
- Specify a culture in string conversion explicitly
Specify a culture in string conversion explicitly There are different methods of grouping symbols, l ...
- 用ATL和MFC来创建ActiveX控件
摘要:目前MFC和ATL代表了两种框架,分别面向不同类型的基于Windows的开发.MFC代表了创建独立的Windows应用的一种简单.一致的方法:ATL提供了一种框架来实现创建COM客户机和服务器所 ...
- curl Array to string conversion 错误
0x00 故障 由于GuzzleHttp在iis上使用错误,于是开始替换其为Unirest,没想到发送了一个curl Array to string conversion 错误 0x01 原因 跟踪调 ...
- Notice:Array to string conversion的问题
如果后台或者前端输出这样的提示: Notice: Array to string conversion 原因是:用 echo 来输出数组,当然会报错,数组应该用print , print_r , 或 ...
- php报错Array to string conversion 解决方案,动态输出数据库列名称
php报错Array to string conversion 解决方案,动态输出数据库列名称 问题:在Windows php5.3环境下使用:<?php echo $row->$keys ...
- 解决warning: #181-D: argument is incompatible with corresponding format string conversion警告
uint8_t NetRSSI=0;uint8_t NetBer=0;uint8_t failtime=0; sscanf(&USART_RX_BUF[0],"%*s%u,%u&qu ...
- php YII2空数组插入报错问题处理 Array to string conversion
问题描述 前端传空数组 [],php接收后处理不当插入数据库时报错Array to string conversion 参数示例 { "id": 0, //ID整型 "t ...
- VS2008中 ATL CLR MFC Win32 区别
ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用MFC,使用API函数编的程序.MFC.ATL和CLR是VC2 ...
随机推荐
- (转)基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍
http://www.cnblogs.com/wuhuacong/p/3344096.html 在前面介绍了一些关于最新基于MVC4+EasyUI的Web开发框架文章,虽然Web开发框架的相关技术文章 ...
- VS Code中编写html(4) 标签的宽高颜色背景设置
1 <!+Tab键--> <!--有两个div标签时,分别设置style,有两种方法--> <div id="div1">第一个div标签:& ...
- JS 猴子
公园里有一只猴子和一堆桃子,猴子每天吃掉桃子总数的一半,把剩下一半中扔掉一个坏的. 到第七天的时候,猴子睁开眼发现只剩下一个桃子.问公园里刚开始有多少个桃子? <!DOCTYPE html> ...
- How many integers can you find HDU - 1796_容斥计数
Code: #include<cstdio> using namespace std; typedef long long ll; const int R=13; ll a[R]; ll ...
- C语言基础 (10) 变量作用域,生命周期 内存结构
01 课程回顾 1.指针数组 注意: 对于数组来说,在使用sizeof的时候a和&a[0]是不一样的, 虽然以%x打印出来他们都是地址 2.值传递 int a; fun(a); int *** ...
- Tarjan算法 (强联通分量 割点 割边)
变量解释: low 指当前节点在同一强连通分量(或环)能回溯到的dfn最小的节点 dfn 指当前节点是第几个被搜到的节点(时间戳) sta 栈 vis 是否在栈中 ans 指强连通分量的数量 top ...
- 【LibreOJ 6277】数列分块入门 1 (分块)
emmm-学下分块~ 区间:数列中连续一段的元素 区间操作:将某个区间[a,b]的所有元素进行某种改动的操作 块:我们将数列划分成若干个不相交的区间,每个区间称为一个块 整块:在一个区间操作时,完整包 ...
- Tensorflow高效读取数据的方法
最新上传的mcnn中有完整的数据读写示例,可以参考. 关于Tensorflow读取数据,官网给出了三种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码 ...
- 游戏开发人员眼中的Unity 3D网页游戏測评报告
眼下.能够实现3D页游的主流技术有Silverlight.XNA.Flash.HTML5和Unity3D. 当中.Unity3D作为一款专注于3D游戏的浏览器插件.最近在国内外页游产品线骚动异常:本人 ...
- 使用UE4公布安卓平台游戏
使用了几天的UE4 ,总算是将游戏在安卓平台执行起来了.当中遇到非常多问题,而且终于依旧有一些问题没能解决. 整体感觉是UE4这款引擎眼下还不够成熟.问题较多. 没有unity使用起来方便. 可是既然 ...