zoukankan      html  css  js  c++  java
  • [转]有关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] = '';
       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();
        }
    }

    如果不知道这点问题,在使用后崩溃时很难查出崩溃原因的。

  • 相关阅读:
    kettle用户手册(7:变量)
    kettle用户手册(3:创建一个数据库链接)
    PDI的steps:(4:Add sequence)
    kettle用户手册(2:创建一个转换或者job)
    vmware vsphere 5虚拟数据中心构建指南(一)
    PDI的step:(1:abort)
    MongoDB在CentOS下的安装(二次修改)
    Cent OS 5.6下安装MongoDB教程
    CentOS5.6安装DNS的Bind服务器
    芒果知识补充(1)mongodb 单机的备份与恢复
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/3995672.html
Copyright © 2011-2022 走看看