[转]有关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 在等 ...
随机推荐
- 如何在 Ubuntu 14.04 里面配置 chroot 环境
你可能会有很多理由想要把一个应用.一个用户或者一个环境与你的 Linux 系统隔离开来.不同的操作系统有不同的实现方式,而在 Linux 中,一个典型的方式就是 chroot 环境. 在这份教程中,我 ...
- Android实战_来电拦截专家
1 项目演示: 2 代码演示: 1)MainActivity类代码: MainActivity类代码: package com.example.phoneinteceptor_one;import j ...
- jquery------隐式迭代
其中Jq方法遍历内部dom数组的过程就叫做[隐式迭代] my.js $(document).ready(function(){ (function($){ $.fn.swapClass=functio ...
- while练习:输入一个班级的人数,然后依次输入学员成绩,计算班级学员的平均成绩和总成绩。
Console.WriteLine("请输入班级的总人数:"); int count = int.Parse(Console.ReadLine()); ;//声明一个循环变量来记录 ...
- System.gc()与Object.finalize()的区别
finalize()是由JVM自动调用的,你可以用System.gc(),但JVM不一定会立刻执行,JVM感觉内存空间有限时,才会开始执行finalize(),至于新的对象创建个数和被收集个数不同是因 ...
- CF440C
C. One-Based Arithmetic time limit per test 0.5 seconds memory limit per test 256 megabytes input st ...
- form表单那点事儿(上) 基础篇
form表单那点事儿(上) 基础篇 做为html中最为常见,应用最广泛的标签之一,form常伴随前端左右.了解更深,用的更顺. 目录: 表单属性 表单元素 常识 模拟外观 表单属性 这个表单展示了fo ...
- 用纯原生js实现jquery的ready函数(两种实现)
第一种实现方式: var dom = new function() { var dom = []; dom.isReady = false; dom.isFunction = function(obj ...
- Spring各个jar包的简介
spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...
- Android - 文件读写操作 总结
在android中的文件放在不同位置,它们的读取方式也有一些不同. 本文对android中对资源文件的读取.数据区文件的读取.SD卡文件的读取及RandomAccessFile的方式和方法进行了整理. ...