[转]有关USES_CONVERSION
转自:http://blog.csdn.net/p40614021/article/details/6778100
ATL:转换宏是各种字符编码之间进行转换的一种很方便的方式,在函数调用时,它们显得非常有用。ATL转换宏的名称是根据下面的模式来命名的[源类型]2[新类型]或者[源类型]2C[新类型]。据有第二种形式的名字的宏的转换结果是常量指针(对应名字中的"C")。
为了使用这些宏,需要先包含atlconv.h头文件。你甚至可以在非ATL工程中包含这个头文件来使用其中定义的宏,因为这个头文件独立于ATL 中的其他部分,不需要一个_Module全局变量。当你在一个函数中使用转换宏时,需要把USES_CONVERSION宏放在函数的开头。它定义了转换 宏所需的一些局部变量
在 mfc 下使用要包含 afxconv.h
atl 下是 atlconv.h
-------------
调用 USES_CONVERSION; 之后就可以使用 OLE2T 等转换的宏
例子 :
Unicode 字符集下的CString转char*
#include <AFXCONV.H>
CString strUnicode(_T("unicode string"));
USES_CONVERSION;
char* pszChar = W2A(strUnicode));
但是!!慎用 USES_CONVERSION!!
USES_CONVERSION是ATL中的一个宏定义。用于编码转换(用的比较多的是CString向LPCWSTR转换)。在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是用来转换类型的,比如我们很常见的问题: 在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKADDR_IN中的inet_a ...
- A2W、W2A、A2T、T2A的使用方法
1.A2W和W2A 在<Window核心编程>,多字节和宽字节之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义 ...
- Unicode字符集下CString与char *转换 (解决中文乱码等)(转)
UniCode 下 CString 转 char* 的方法的文章有很多,但是大部分都是在互相转载,看了那么多资料,仍然没有解决乱码的问题,后来从一个论坛的一条回复里面找到了正确的方法,特此拿出来与大家 ...
- CString转string
如题,找了半天... //CString转string USES_CONVERSION; CString temp; temp = _T("kjdsaflkjdlfkj"); ch ...
- char wchar 互转 多字符 宽字符 的N种方式
1: 用 CString 如果没有mfc 可以用 ATL 中的 CString #include <atlstr.h> CStringA v1 = "111&quo ...
- MFC字符串转化成16进制
//CString m_str = _T("11"); //USES_CONVERSION; //char *m_cc = T2A(m_str); //BYTE m_bb; //s ...
- 【转】COM技术内幕(笔记)
COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...
- 如何使用BHO定制你的Internet Explorer浏览器
原文出处:Browser Helper Objects: The Browser the Way You Want It一.简介 有时,你可能需要一个定制版本的浏览器.在这种情况下,你可以自由地把一些 ...
- 一次Mutex死锁的原因探究
1.现象 最近项目中调出一个bug,某些时候程序会卡死不动,用windbg进行加载后用 ~*kb 命令列出所有的线程栈调用,发现有多个线程调用 WaitForMultipleObjects 在等 ...
随机推荐
- PHP中PDO的配置与说明
住[PDO是啥] PDO是PHP5新加入的一个重大功能,因为在PHP5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么php_mysql.dll.php_pgsql.dll ...
- PHP输出表格的方法
<?php function table($n) //几行几列表 { echo'<table border="1" width="500" heig ...
- 织梦(dedecms) 5.7 /plus/car.php sql注入0day
测试方法: @Sebug.net dis本站提供程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负! <?php $host=$argv[1]; $path=$argv[2]; $ ...
- C# 设置开机自动启动(注册表方式)
.NET技术交流群 199281001 .欢迎加入. using System; using System.Collections.Generic; using System.Linq; using ...
- Android Studio 设置不自动缩进匿名内部类
Android Studio 会默认缩进匿名内部类代码,这让人感觉有些不大适应,可以使用下面的方法进行取消. 取消选中橙色框前的几个复选框即可.
- jquery json ajax -2
如果使用的是虚拟空间, 那么你不能操纵/配置服务器上的php.ini配置文件 但是可以在自己的php文件中, 通过ini_set(...), 和一些对应的函数, 去重置(临时的,仅在当前文件中生效的) ...
- 手机wifi密码的保存位置
subjects: adj. 受制于...的, 被统治的; n. 主题,学科, 国民 the subjects had to kneel down before the king. kneel -& ...
- ASP.NET MVC学习笔记-----使用自定义的View Engine
我们都知道在ASP.NET MVC中自带了Razor View Engine,Razor十分的强大,可以满足我们绝大部分的需要.但是ASP.NET MVC的高度可扩展性,使我们可以使用自定义的View ...
- Cocos2d坐标系转换
Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系(高中数学里面那种). 笛卡尔坐标系 笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenGL坐标系为笛卡尔右 ...
- cocos2d回忆
凭借自己的回忆想想看自己都学到了那些知识,这是小学的时候当初中老师的外公给我说的,现在想想,CCDirector,CCNode,CCScene,CCSprite这几个类,然后是坐标,锚点,CCNode ...