Heath's Blog

There is no end, it is just the beginning! - A Game Developer's Notes

邪恶的Windows

众所周知,WIN32 API分为Unicode版和非Unicode版,由于Unicode是后来加进来的,为了向下兼容,微软的兄弟们使用了宏来统一接口,如MessageBox的定义:
#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE
这个方法并不像看上去的那么完美,请看下面这段无辜的代码:
class MyClass
{
 
public:
    
void MessageBox();
 
}
;
当项目中包含windows.h,更确切点说是winuser.h,如果未使用Unicode,在预编辑阶段,MyClass::MessageBox会被替换成MyClass::MessageBoxA,而后让人摸不着头脑的编译错误便跳了出来。据笔者经验,与这些API同名的几率其实很少,但正是因为少,当出现此种编译错误时却让人不知如何是好。一种简单的解决方法便是在MyClass头文件中undef掉MessageBox:
#ifdef MessageBox
#undef MessageBox
#endif

posted on 2009-07-29 23:38 Heath 阅读(2770) 评论(24)  编辑 收藏 引用 所属分类: Programming Language

Feedback

# re: 邪恶的Windows 2009-07-29 23:44 安德斯

换个名字撒,呵呵,难道情有独钟啊  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 00:28 紫夜苍狼

偶也觉得,换个名字就好了啊。  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 04:25 someone

This is an overstatement. There are tons of defs in the system header files, why you don't complain about them?  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 08:36 猫猫

说明微软高啊
微软能把这么破的玩意组织了这么都年 ,你能说不好吗?
存在的就是合理的!  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 08:47 凡客诚品

不错啊!  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-30 09:08 Davy.xu

干嘛用名词当函数名,重名是肯定的  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-30 10:00 simon

麻烦都是自找的,你开个命名空间不就是了  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-30 10:06 Bill Hsu

谢谢LZ分享  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 11:18 abettor

确实是很大的陷阱,这种宏很多,一不小心就掉井里。
如果自己编程序的话,名字改了也就改了,即使改成阿猫阿狗也无所谓。但是如果是团队开发,而且这些名字已经规定在了接口规范里,就不是那么容易改的了。
况且,作为好的编程习惯,保持方法名的可读性是非常重要的!  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-30 12:55 cc

这种编译错误很好找,博主不会看不懂错误提示吧  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 12:58 zwp

@simon
宏是通杀啊,没有用的。  回复  更多评论   

# re: 邪恶的Windows 2009-07-30 17:15 岳阳

命名空间  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-30 18:55 欲三更

这个还真么注意到,放在命名空间里也会替换么?  回复  更多评论   

# re: 邪恶的Windows 2009-07-31 09:02 fuckyou

简直是扯淡。  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-31 11:24 Heath

@岳阳
@fuckyou
自己实践去吧,别没事在这里乱吐口水...  回复  更多评论   

# re: 邪恶的Windows 2009-07-31 16:06 cyberamoeba

存在就是合理。在 Windows 平台上写东西,这种错误不应该犯。就像你用 C 写程序,你总不能要求用 do 当函数名是应该被接受的。  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-31 16:46 Heath

@cyberamoeba
呵呵,这句话真有意思,你能像记住C语言关键字那样记住那么多Windows API吗?当你发现自己连命名一个SetPort函数的权力都没有的时候,你还会这样想吗?上面例子中的MessageBox,当然是个人都知道。  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-07-31 17:25 hdqqq

你有命名MessageBox的权利,条件是别去包含 <windows.h>
既然你包含了这个文件,那就乖乖换名字吧。  回复  更多评论   

# re: 邪恶的Windows 2009-07-31 23:08 路过

我也遇到过类似的问题,当时没有细究,只是重新命名了,原来是宏的问题。。。  回复  更多评论   

# re: 邪恶的Windows 2009-08-01 14:27 wof

@hdqqq
undef掉MessageBox,直接调用MessageBoxA或者MessageBoxW不就行啦,真是OUT得不行了。。。  回复  更多评论   

# re: 邪恶的Windows[未登录] 2009-08-05 08:53 Alex

你认为windows该怎么做才能做到兼容ascii和Unicode呢?自己定义的函数加个项目名称或者单位的前缀都是不错的。看看jni生成的c接口  回复  更多评论   

# re: 邪恶的Windows 2009-08-05 15:22 陈梓瀚(vczh)

既然你知道了原因,那出现了这个错误信息你肯定立刻就反应过来的了。  回复  更多评论   

# re: 邪恶的Windows 2009-12-05 21:32 parkerzhu

编译器应该负责  回复  更多评论   

# re: 邪恶的Windows 2010-09-22 21:01 路过

刚才测试过,在vs2008中,用了命名空间是不会有问题的。。。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理