USES_CONVERSION宏定义

USES_CONVERSION宏定义USES_CONVERSION是用来转换类型的(比如T2A等转换需用此宏),比如我们很常见的问题:在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKADDR_IN中的inet_addr却是const char *我们就不能直接用CString来用。我们就可以使用T2A()宏了。 SOCKADDR_IN localaddr; …

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺



USES_CONVERSION是用来转换类型的(比如T2A等转换需用此宏),比如我们很常见的问题:

在Socket编程时候,我们的IP地址从界面上输进去一般都使用CString类型的,可是在SOCKADDR_IN中的inet_addr却是const char *我们就不能直接用CString来用。我们就可以使用T2A()宏了。

    SOCKADDR_IN localaddr;   
    CString m_IP = L"192.168.1.2";
    USES_CONVERSION;
    localaddr.sin_family = AF_INET;
    localaddr.sin_addr.S_un.S_addr = inet_addr(T2A(m_IP));

当然使用USES_CONVERSION也是要注意一个很重要的问题。

USES_CONVERSION它是在堆栈上分配空间的,也就是说你在你在函数未结束就不会被释放掉。所有要注意不要在一个函数中用while循环执行它,不然栈空间就马上会分配完(栈空间一般只有2M,很小)。



关于USES_CONVERSION宏的详细介绍

首先,介绍下USES_CONVERSION为何物。

USES_CONVERSION是ATL中的一个宏定义。用于编码转换(用的比较多的是CString向LPCWSTR转换)。通俗的说,就是用了这个宏后,就可以用一系列的字符串转换宏,有OLE到T,T到OLE,OLE到W,W到OLE等等,非常方便。或者说,这个宏会告诉编译器,在紧接的代码中我们要用OLE库中代码(如ansi到unicode的A2W(…))的转换宏,不加USES_CONVERSION在使用A2W会出错。

要想使用这个宏,因为它是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 ::在堆栈上分配内存。

_alloca从程序堆栈中分配大小字节。当调用函数退出时,分配的空间将自动释放。因此,不要将alloca返回的指针值作为参数传递给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();
    }
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170936.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python 冒泡排序_python

    Python 冒泡排序_python要学习冒泡排序必须知道它的原理:冒泡排序算法的原理如下:比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。例子:1,2,3,4,5,6就拿1到6来举例子吧!这里面有n个数字,你要对其进…

    2022年10月16日
    5
  • HTML, CSS学习笔记(完整版)[通俗易懂]

    HTML, CSS学习笔记(完整版)

    2022年1月31日
    38
  • expect java,Expect 使用详解「建议收藏」

    expect java,Expect 使用详解「建议收藏」第1章expect概括expect期待expect是Unix系统中用来进行自动化控制和测试的软件工具,由DonLibes制作,作为Tcl脚本语言的一个扩展,应用在交互式软件中如telnet,ftp,Passwd,fsck,rlogin,tip,ssh等等。该工具利用Unix伪终端包装其子进程,允许任意程序通过终端接入进行自动化控制;也可利用Tk工具,将交互程序包装在X11的图形用户界面中。…

    2025年5月31日
    4
  • c语言中fprintf_c语言输出函数printf

    c语言中fprintf_c语言输出函数printf目录一.fprintf函数简介二.fprintf函数使用三.猜你喜欢零基础C/C++学习路线推荐:C/C++学习目录>>C语言基础入门一.fprintf函数简介fprintf是C/C++中的一个格式化库函数,位于头文件中,其作用是格式化输出到一个流文件中;函数原型为/**描述:fputs函数是向指定的文件写入一个字符串**参数:*[in]stream:文件指针句柄;*[in]format:格式化字符串,

    2022年10月10日
    4
  • mysql—如何获取有性能问题的sql

    mysql—如何获取有性能问题的sql

    2020年11月12日
    203
  • 企业网站seo维护_seo怎么才能优化好

    企业网站seo维护_seo怎么才能优化好  一般说来,URL中包含关键词对网站优化确实会有所帮助。不过从品牌效果考虑,用品牌名称做域名应该是比较合适的。不要走急功近利误区。独立域名更能获得搜索引擎的认可。调查显示:大多数搜索引擎排名时对那些不具备独立域名的网站赋予较小的“重要性”。      网站优化的目的是用合理的手段(不是作弊),对网站源代码进行优化,使之对搜索引擎更友好,更符合排名规则一个站点的排名70%是靠网站优化

    2025年12月16日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号