关于USES_CONVERSION宏
关于USES_CONVERSION宏
首先,介绍下USES_CONVERSION为何物。
USES_CONVERSION是ATL中的一个宏定义。用于编码转换(用的比较多的是CString向LPCWSTR转换)。通俗的说,就是用了这个宏后,就可以用一系列的字符串转换宏,有OLE到T,T到OLE,OLE到W,W到OLE等等,非常方便。或者说,这个宏会告诉编译器,在紧接的代码中我们要用OLE库中代码(如ansi到unicode的A2W(...))的转换宏,不加USES_CONVERSION在使用A2W会出错。
要想使用这个宏,因为它是ATL库带的,所以要加上头文件#include <atlconv.h>。
使用USES_CONVERSION一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放。如果在一个循环中,这个宏被反复调用几万次,将不可避免的产生stackoverflow。
在一个函数的循环体中使用A2W等字符转换宏可能会引起栈溢出。
#include <atlconv.h>
void fn()
{
while(true)
{
{
USES_CONVERSION;
DoSomething(A2W("SomeString"));
}
}
}
让我们来分析以上的转换宏:
#define A2W(lpa) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert)))
#define ATLA2WHELPER AtlA2WHelper
inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp)
{
ATLASSERT(lpa != NULL);
ATLASSERT(lpw != NULL);
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don't worry about the number of chars
lpw[0] = '\0';
MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars);
return lpw;
}
关键的地方在alloca内存分配内存上。
#define alloca _alloca
_alloca
Allocates memory on the stack.
Remarks
_alloca allocates size bytes from the program stack. The allocated space is automatically freed when the calling function
exits. Therefore, do not pass the pointer value returned by _alloca as an argument to free.
问题就在这里,分配的内存是在函数的栈中分配的。而VC编译器默认的栈内存空间是2M。当在一个函数中循环调用它时就会不断的分配栈中的内存。
以上问题的解决办法有两个:
1. 自己写字符转换函数
Function that safely converts a 'WCHAR' String to 'LPSTR':
char* ConvertLPWSTRToLPSTR (LPWSTR lpwszStrIn)
{
LPSTR pszOut = NULL;
if (lpwszStrIn != NULL)
{
int nInputStrLen = wcslen (lpwszStrIn);
// Double NULL Termination
int nOutputStrLen = WideCharToMultiByte (CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
pszOut = new char [nOutputStrLen];
if (pszOut)
{
memset (pszOut, 0x00, nOutputStrLen);
WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
}
}
return pszOut;
}
2. 把字符转换部分放到一个函数中处理。
void fn2()
{
USES_CONVERSION;
DoSomething(A2W("SomeString"));
}
void fn()
{
while(true)
{
fn2();
}
}
如果不知道这点问题,在使用后崩溃时很难查出崩溃原因的。
关于USES_CONVERSION宏相关推荐
- USES_CONVERSION宏定义
USES_CONVERSION是用来转换类型的(比如T2A等转换需用此宏),比如我们很常见的问题: 在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKA ...
- ATL 和 MFC 字符转换宏
ATL 和 MFC 字符转换宏 ATL3.0 Ø ATL3.0中的W2T ,T2W等一系列宏很方便,但一定要小心,它们从栈上分配内存,直到调用它的函数返回前,该内存不会被释放,如果在一个循环 ...
- 【转】MFC 各类型相互转换
MFC下的常用字符串数据类型表示的含义: L:Long 长 P:Point 指针 C:Const 常量 W:Wchar_t 宽字符 T:TCHAR STR:String 字符串 在看看MF ...
- C++字符串完全指引之二 —— 字符串封装类
C++字符串完全指引之二 -- 字符串封装类 原著:Michael Dunn 作者:Chengjie Sun 原文出处:CodeProject:The Complete Guide to C++ St ...
- C/C++中char *与wchar_t*的几种转换方法
多字节(char *)和宽字符(wchar_t *)之间的转换有几种方式,下面按照从通用到特殊的顺序逐一介绍. 1.C库函数 1.1 关键函数 (1) setlocale() 功能:配置地域化信息 头 ...
- 关于Char* ,CString ,WCHAR*之间的转换问题
GDI+所有类的接口函数如果要传递字符串作为参数的话,似乎都用UNICODE串,即WCHAR*.我开始也被整得晕头转向,因为窗口编程所用往往是CString,用IO流读文件数据又得到char *.得益 ...
- 转 ASCII, DBCS,UNICODE小结
引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...
- ASCII, DBCS,Unicode小结
引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...
- ASCII, DBCS, Unicode【上】
引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...
最新文章
- python编程自学能学会吗-python编程还能自学?怎么能学好? - 【大连东软睿道】
- 2019 GDUT Rating Contest II : Problem G. Snow Boots
- spring cloud gateway url重写
- ResNet压缩20倍,Facebook提出新型无监督模型压缩量化方法
- matplotlib散点图点大小_机器学习Web应用:matplotlib教程
- 西瓜书+实战+吴恩达机器学习(十六)半监督学习(半监督SVM、半监督k-means、协同训练算法)
- sql语句查询结果合并union all用法_数据库技巧
- 第五章 二叉树(a)树
- 最新如何在CentOS6版本上安装Teamviewer
- 【计算电磁学】真空中电磁波传播的MATLAB一维FDTD仿真程序
- oracle arm版本,Oracle版本区别
- Hbuilder里运行到手机或模拟器手机和电脑配置
- 《鹰猎长空》讲述戏曲与电影的渊源
- 学习历程——词法分析器
- 入门训练圆的面积_入门
- Room数据库添加字段遇到的问题记录
- 针对文件流转Base64的操作
- java毕业设计大连环保公益网Mybatis+系统+数据库+调试部署
- 虚拟机设置共享文件夹
- CSS雪碧图demo(含雪碧代码)
热门文章
- 10532: 花 [dp]
- HTML5.1 推荐中 1.5.3. Extensibility 段落翻译
- 0909 对编译原理的想法
- [转]ASP.NET刷新页面的六种方法
- 数据库MySQL--常见基础命令
- re 模块, 正则表达式 \w+\d+ 的重复问题引发的题目解析
- 苹果自动驾驶“排名垫底”,每1.1英里就发生一次脱离...
- SSH 无法远程登录问题的处理思路
- 如何从SharePoint Content DB中查询List数据
- RHCE认证培训+考试七天实录(三)