关于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宏相关推荐

  1. USES_CONVERSION宏定义

    USES_CONVERSION是用来转换类型的(比如T2A等转换需用此宏),比如我们很常见的问题: 在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKA ...

  2. ATL 和 MFC 字符转换宏

    ATL 和 MFC 字符转换宏  ATL3.0 Ø     ATL3.0中的W2T ,T2W等一系列宏很方便,但一定要小心,它们从栈上分配内存,直到调用它的函数返回前,该内存不会被释放,如果在一个循环 ...

  3. 【转】MFC 各类型相互转换

    MFC下的常用字符串数据类型表示的含义: L:Long  长 P:Point  指针 C:Const  常量 W:Wchar_t  宽字符 T:TCHAR  STR:String  字符串 在看看MF ...

  4. C++字符串完全指引之二 —— 字符串封装类

    C++字符串完全指引之二 -- 字符串封装类 原著:Michael Dunn 作者:Chengjie Sun 原文出处:CodeProject:The Complete Guide to C++ St ...

  5. C/C++中char *与wchar_t*的几种转换方法

    多字节(char *)和宽字符(wchar_t *)之间的转换有几种方式,下面按照从通用到特殊的顺序逐一介绍. 1.C库函数 1.1 关键函数 (1) setlocale() 功能:配置地域化信息 头 ...

  6. 关于Char* ,CString ,WCHAR*之间的转换问题

    GDI+所有类的接口函数如果要传递字符串作为参数的话,似乎都用UNICODE串,即WCHAR*.我开始也被整得晕头转向,因为窗口编程所用往往是CString,用IO流读文件数据又得到char *.得益 ...

  7. 转 ASCII, DBCS,UNICODE小结

    引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...

  8. ASCII, DBCS,Unicode小结

    引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...

  9. ASCII, DBCS, Unicode【上】

    引言 毫无疑问,我们都看到过像 TCHAR, std::string, BSTR 等各种各样的字符串类型,还有那些以 _tcs 开头的奇怪的宏.你也许正在盯着显示器发愁.本指引将总结引进各种字符类型的 ...

最新文章

  1. python编程自学能学会吗-python编程还能自学?怎么能学好? - 【大连东软睿道】
  2. 2019 GDUT Rating Contest II : Problem G. Snow Boots
  3. spring cloud gateway url重写
  4. ResNet压缩20倍,Facebook提出新型无监督模型压缩量化方法
  5. matplotlib散点图点大小_机器学习Web应用:matplotlib教程
  6. 西瓜书+实战+吴恩达机器学习(十六)半监督学习(半监督SVM、半监督k-means、协同训练算法)
  7. sql语句查询结果合并union all用法_数据库技巧
  8. 第五章 二叉树(a)树
  9. 最新如何在CentOS6版本上安装Teamviewer
  10. 【计算电磁学】真空中电磁波传播的MATLAB一维FDTD仿真程序
  11. oracle arm版本,Oracle版本区别
  12. Hbuilder里运行到手机或模拟器手机和电脑配置
  13. 《鹰猎长空》讲述戏曲与电影的渊源
  14. 学习历程——词法分析器
  15. 入门训练圆的面积_入门
  16. Room数据库添加字段遇到的问题记录
  17. 针对文件流转Base64的操作
  18. java毕业设计大连环保公益网Mybatis+系统+数据库+调试部署
  19. 虚拟机设置共享文件夹
  20. CSS雪碧图demo(含雪碧代码)

热门文章

  1. 10532: 花 [dp]
  2. HTML5.1 推荐中 1.5.3. Extensibility 段落翻译
  3. 0909 对编译原理的想法
  4. [转]ASP.NET刷新页面的六种方法
  5. 数据库MySQL--常见基础命令
  6. re 模块, 正则表达式 \w+\d+ 的重复问题引发的题目解析
  7. 苹果自动驾驶“排名垫底”,每1.1英里就发生一次脱离...
  8. SSH 无法远程登录问题的处理思路
  9. 如何从SharePoint Content DB中查询List数据
  10. RHCE认证培训+考试七天实录(三)