- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
VC中一个关于宏的使用问题
VC中一个关于宏的使用问题
这儿是个关于宏的问题,我曾用过ATL的串转换宏,包括W2A,开始有些东西我还不太明白。为了使用这些宏,必须在函数的开始处用USES_CONVERSION来初始化某些局部变量。用就用吧,但是看看这个宏的定义,它有类似下面的代码:
1.// 在atlconv.h文件中2.#define USES_CONVERSION \
3.int?_convert; _convert; \
4.UINT?_acp = GetACP(); _acp; \
5.LPCWSTR?_lpw; _lpw; \?
6.LPCSTR?_lpa; _lpa
为什么它们用“int x;x;”——这种后面跟着变量的声明?
很多人都碰到过这个令人困惑的问题,后来发现简单的答案是:禁止编译器的警告信息(warning)。如果单独有一行代码:
1.int?x;
且从来没有使用过x,那么编译器汇报错“unreferenced local variable:x”,意思是未引用过的局部变量x,如果将警告信息的输出调到最大。为了避免讨厌的警告,USES_CONVERSION引用声明的变量。
1.int?x;?// 声明2.x;?// 使用这个变量
1.void?MyFunc(int?x,?char?y)
2.{
3.x;
4.y;
5.…
6.}
当然,现在用下面的代码可以更有效地完成同样的事情:
1.// 参数 x 不是用2.void?MyFunc(int?/* x */)?
3.{
4.…
5.}
也就是说声明参数,但不给它起名,不能这样使用局部变量;必须显式地引用它。这样做不会增加任何指令到代码中。最多可能多增加几个字节到堆栈(为x预留空间)。灵巧的编译器甚至不会操心x从来没有被使用过——虽然好奇心可能想知道:如果编译器够厉害,知道了从没有使用x,为什么要抱怨(编译出错)呢?答案是因为苛刻的程序员(且编程能力与个人的记性有关)使用编译警告提醒自己删除某部分代码时发生变量荒废。这种警告在C时代很有用,你必须在每个函数的顶部声明变量,这就远离了实用它们的代码。
现在来看看另一个问题:为什么在开始位置要用USES_CONVERSION?即为什么W2ACo之类的宏还需要另外的宏声明自己的变量;为什么不直接在W2A中声明这个变量?
1.#define W2A(x) \
2.int?_convert; _convert; \
3.……etc
很明显这样做不行,因为如果你使用W2A两次,得到一个复制的变量。那为什么不把整个宏放进花括弧创建新的范围?
1.#define W2A(x) Q{ \
2.int?_convert; _convert; \
3.…… \
4.}
这样解决了命名冲突,但不能进行如下编码:
1.DoSomething(W2A(pwstr));
没有办法从代码块返回值,所以不能在函数调用中传递W2A。真笨啊,那么内联函数怎么样?
1.inline?LPCSTR?W2A(LPWSTR?w) {
2.int_convert;
3.……
4.}
这解决了范围问题——任何W2A需要的变量多可以在这个函数中,在自己的范围内声明,不需要另外的宏。它也提供了一种返回值的方式,使你可以在函数调用和赋值中使用W2A(x)。但是这种方法不灵,也是因为W2A的缘故和其它的宏更复杂。
不管什么时候进行Unicode转换,都不能就地转换串,必须分配一个临时串容纳被转换的字节。典型地,通过调用new分配一个串:
1.int?len = MultiByteToWideChar(...,?
2.mystr, NULL, 0);?// 或的长度
3.LPWSTR?p =?new?WCHAR[nLen];?// 分配内存
4.MultiByteToWideChar(...,p,len);?// 转换
5.SomeCOMFunction(p);?// 使用之
6.delete?[] p;?// 销毁
1.// 简化版2.#define A2W(s) \
3._len = 2*strlen(s);
4.AfxA2WHelper((LPWSTR)alloca(_len);
AfxA2Whelper是一个调用MultiByteToWideChar的辅助函数。A2W使用2*len巧妙地避免了两次调用MultiByteToWideChar。但A2W及其它转换宏真正聪明的地方是不调用new操作分配临时串,而是调用alloca——在栈中分配字节,而不是在堆中。这样做非常快,因为编译器要做的只是增加栈指针。不调用函数,不处理内存块。它也避免了内存碎片,并且也没有必要调用delete操作,因为当控制离开alloca被调用的地址后,内存被自动释放。这正好说明了为什么A2W不能时内联函数;如果是的话
您可能关注的文档
最近下载
- pep人教版六年级上学期英语全学期课时作业练习题.doc VIP
- 电气控制与PLC教案.pdf VIP
- NBT20277-2014 A240(S32101)双相不锈钢焊接规范.pdf VIP
- 2025秋人教版(PEP)(2024)三年级上册英语教学计划.docx VIP
- 初一英语文化课件.pptx VIP
- 高标准农田监理大纲方案投标文件(技术方案).doc
- 第一单元 第1课《可爱的我们》核心素养教学设计 2025湘美版美术三年级上册.pdf
- 2025云南省中职职教高考职业技能考烹饪类专业理论测试模拟05.doc VIP
- 客服人员心态与沟通技巧培训PPT.pptx VIP
- 农村公共卫生与健康促进.pptx VIP
文档评论(0)