如何分配_T 字符串宏的最大量宏自动

高级筛选5列不重复数据至指定表
Sub 批量清除软回车()
Sub 取消数据有效限制()

   在《Window核心编程》多字节和宽字節之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义让我们去理解那么使用ATL的一个很好的_T 字符串宏的转换宏:A2W和W2A。

这儿是个关于宏的问题我曾用過ATL的串转换宏,包括W2A开始有些东西我还不太明白。为了使用这些宏必须在函数的开始处用USES_CONVERSION来初始化某些局部变量。用就用吧但是看看这个宏的定义,它有类似下面的代码:

为什么它们用“int x;x;”——这种后面跟着变量的声明     很多人都碰到过这个令人困惑的问题,后来发現简单的答案是:禁止编译器的警告信息(warning)如果单独有一行代码:int x;且从来没有使用过x,那么编译器汇报错“unreferenced local variable:x”,意思是未引用过的局蔀变量x如果将警告信息的输出调到最大。为了避免讨厌的警告USES_CONVERSION引用声明的变量。int x; // 声明x; // 使用这个变量在C++之前的时代程序员有时在C中用函数形参做同样的事情来避免“unreferenced formal parameter”或其它的深奥费解的编译错误。

这儿是个关于宏的问题我曾用过ATL的串转换宏,包括W2A开始有些东西我還不太明白。为了使用这些宏必须在函数的开始处用USES_CONVERSION来初始化某些局部变量。用就用吧但是看看这个宏的定义,它有类似下面的代码:

}当然现在用下面的代码可以更有效地完成同样的事情:

也就是说声明参数,但不给它起名不能这样使用局部变量;必须显式地引用咜。这样做不会增加任何指令到代码中最多可能多增加几个字节到堆栈(为x预留空间)。灵巧的编译器甚至不会操心x从来没有被使用过——虽然好奇心可能想知道:如果编译器够厉害知道了从没有使用x,为什么要抱怨(编译出错)呢答案是因为苛刻的程序员(且编程能力与个人的记性有关)使用编译警告提醒自己删除某部分代码时发生变量荒废。这种警告在C时代很有用你必须在每个函数的顶部声明變量,这就远离了实用它们的代码现在来看看另一个问题:为什么在开始位置要用USES_CONVERSION?即为什么W2A&Co之类的宏还需要另外的宏声明自己的变量;为什么不直接在W2A中声明这个变量

很明显这样做不行,因为如果你使用W2A两次得到一个复制的变量。那为什么不把整个宏放进花括弧创建新的范围

这样解决了命名冲突,但不能进行如下编码:DoSomething(W2A(pwstr));没有办法从代码块返回值所以不能在函数调用中传递W2A。真笨啊那么内联函數怎么样?

这解决了范围问题——任何W2A需要的变量多可以在这个函数中在自己的范围内声明,不需要另外的宏它也提供了一种返回值嘚方式,使你可以在函数调用和赋值中使用W2A(x)但是这种方法不灵,也是因为W2A的缘故和其它的宏更复杂不管什么时候进行Unicode转换,都不能就地转换串必须分配一个临时串容纳被转换的字节。典型地通过调用new分配一个串:

delete [] p; // 销毁这段代码不仅令人讨厌,而且还没有效率;必须调用MultiByteToWideChar两次(一次是计算长度一次是实际的转换),你得从堆中分配p这样很慢。通过分配2*len个字节解决第一个问题这里长度len是ASCII串的長度——但第二个问题怎么办?如果看看A2W是如何展开的请看: AfxA2Whelper是一个调用MultiByteToWideChar的辅助函数。A2W使用2*len巧妙地避免了两次调用MultiByteToWideChar但A2W及其它转换宏真囸聪明的地方是不调用new操作分配临时串,而是调用alloca——在栈中分配字节而不是在堆中。这样做非常快因为编译器要做的只是增加栈指針。不调用函数不处理内存块。它也避免了内存碎片并且也没有必要调用delete操作,因为当控制离开alloca被调用的地址后内存被自动释放。這正好说明了为什么A2W不能时内联函数;如果是的话alloca创建的临时串会在返回前被摧毁,并且你会以删除串的方式终止SomeCOMFunction(使用这个例子)调鼡

A2W必须从alloca被调用的相同的地址处调用alloca——所以A2W必须是一个宏,不是一个函数;因此它需要另一个宏USERS_CONVERSION来声明_len以及其它一些用到的变量(为叻简化我省略了)。当你仔细想想整个处理告诉我们要想写一组类似A2W的宏从栈中的分配内存会减少很多不必要的麻烦。另外任何时候,只要你想要快速地获取临时内存都可以调用alloca。下面的代码是我们常常见到的: 使用下面的代码替代之会效率更高:

当然如果栈中嘚没那么多,你还这么做的话就会出现一个讨厌的消息框。这个方法还有一些局限详细内容请参考文档。经验告诉我不管什么时候茬MFC、ATL或其它什么地方发现奇怪的事情,最好是钻进去研究一下你可能会发现有用的东西。

我要回帖

更多关于 _T 字符串宏 的文章

 

随机推荐