转自: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的更多相关文章

  1. USES_CONVERSION的使用和注意

    USES_CONVERSION是用来转换类型的,比如我们很常见的问题: 在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKADDR_IN中的inet_a ...

  2. A2W、W2A、A2T、T2A的使用方法

    1.A2W和W2A 在<Window核心编程>,多字节和宽字节之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义 ...

  3. Unicode字符集下CString与char *转换 (解决中文乱码等)(转)

    UniCode 下 CString 转 char* 的方法的文章有很多,但是大部分都是在互相转载,看了那么多资料,仍然没有解决乱码的问题,后来从一个论坛的一条回复里面找到了正确的方法,特此拿出来与大家 ...

  4. CString转string

    如题,找了半天... //CString转string USES_CONVERSION; CString temp; temp = _T("kjdsaflkjdlfkj"); ch ...

  5. char wchar 互转 多字符 宽字符 的N种方式

    1:  用 CString  如果没有mfc 可以用 ATL 中的 CString  #include <atlstr.h>     CStringA v1 = "111&quo ...

  6. MFC字符串转化成16进制

    //CString m_str = _T("11"); //USES_CONVERSION; //char *m_cc = T2A(m_str); //BYTE m_bb; //s ...

  7. 【转】COM技术内幕(笔记)

    COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...

  8. 如何使用BHO定制你的Internet Explorer浏览器

    原文出处:Browser Helper Objects: The Browser the Way You Want It一.简介 有时,你可能需要一个定制版本的浏览器.在这种情况下,你可以自由地把一些 ...

  9. 一次Mutex死锁的原因探究

    1.现象    最近项目中调出一个bug,某些时候程序会卡死不动,用windbg进行加载后用 ~*kb 命令列出所有的线程栈调用,发现有多个线程调用 WaitForMultipleObjects 在等 ...

随机推荐

  1. POJ1860Currency Exchange(Bellman + 正权回路)

    Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 23938   Accepted: 867 ...

  2. json格式不对引起的报错

    报JSONDecondeError这种类型的错误的时候就要检查下json格式是否是正确的了,这里提供一个http://www.bejson.com/ Traceback (most recent ca ...

  3. Matalab IFS分形算法

    IFS 算法代码 function IFS_draw(M,p) N=; :length(p); eval(['a',num2str(k),'=reshape(M(',num2str(k),',:),2 ...

  4. Unity-Tween

    1.GoKit 免费开源 AssetStore:https://www.assetstore.unity3d.com/en/#!/content/3663 下载地址:https://github.co ...

  5. JS 显示时间与倒计时练习

    显示时间与倒计时 HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  6. ping 和 traceroute 命令

    ping 和 traceroute 命令 ping 程序 就是发送一个ICMP查询报文给某服务器,以测试该服务器是否可达. 当返回ICMP回显应答时,要打印出序列号.TTL,和往返时间:   [roo ...

  7. windows2003安全加固脚本

    @echo off title= Windwos/index.html' target='_blank'>Windows Security echo. echo **************** ...

  8. Mvc3提交表格验证(转载)

    Model层:using System;using System.Collections.Generic;using System.Linq;using System.Web;using System ...

  9. JAVA如何调用C/C++方法

    JAVA如何调用C/C++方法 2013-05-27 JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能.解决JAVA对本地操作的 ...

  10. [实战]MVC5+EF6+MySql企业网盘实战(28)——其他列表

    写在前面 本篇文章将实现,其他文件类型的列表. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战]MVC5+EF ...