热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于USES_CONVERSION宏

关于USES_CONVERSION宏首先,介绍下USES_CONVERSION为何物。USES_CONVERSION是ATL中的一个宏定义。用于编码转换ÿ

关于USES_CONVERSION宏

首先,介绍下USES_CONVERSION为何物。

USES_CONVERSIONATL中的一个宏定义。用于编码转换(用的比较多的是CStringLPCWSTR转换)。通俗的说,就是用了这个宏后,就可以用一系列的字符串转换宏,有OLET,TOLE,OLEW,WOLE等等,非常方便。或者说,这个宏会告诉编译器,在紧接的代码中我们要用OLE库中代码(ansiunicodeA2W(...))的转换宏,不加USES_CONVERSION在使用A2W会出错。

要想使用这个宏,因为它是ATL库带的,所以要加上头文件#include

使用USES_CONVERSION一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放。如果在一个循环中,这个宏被反复调用几万次,将不可避免的产生stackoverflow

在一个函数的循环体中使用A2W等字符转换宏可能会引起栈溢出。

#include

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();

    }

}

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


推荐阅读
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 在C#编程中,数值结果的格式化展示是提高代码可读性和用户体验的重要手段。本文探讨了多种格式化方法和技巧,如使用格式说明符、自定义格式字符串等,以实现对数值结果的精确控制。通过实例演示,展示了如何灵活运用这些技术来满足不同的展示需求。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
author-avatar
倒骑毛驴笑看人生gnWC_659
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有