别人的库#define命名冲突
很难为这个问题想出一个合适的标题。 无论如何...
我目前正在为我的游戏开发 GUI SDL。 我已经完成了软件绘图,正准备开始绘制其中的 OpenGL 部分,这时出现了一个奇怪的错误。 我包含了“SDL/SDL_opengl.h”标头并进行编译。 它抛出“错误 C2039:'DrawTextW':不是'GameLib::FontHandler'的成员”,这是一个足够简单的错误,但我没有任何称为 DrawTextW 的东西,只有 FontHandler::DrawText。 我搜索 DrawTextW 并在标题“WinUser.h”的 #define 调用中找到它!
//WinUser.h
#define DrawText DrawTextW
显然它用 DrawTextW 替换了我的 DrawText! 我怎样才能阻止它像这样溢出到我的代码中?
改变我自己的函数名称是一件小事,但是像这样的命名冲突看起来非常危险,我真的很想知道如何避免它们。
干杯!
Hard to come up with a proper title for this problem. Anyway...
I'm currently working on a GUI for my games in SDL. I've finished the software drawing and was on my way to start on the OpenGL part of it when a weird error came up. I included the "SDL/SDL_opengl.h" header and compile. It throws "error C2039: 'DrawTextW' : is not a member of 'GameLib::FontHandler'", which is a simple enough error, but I don't have anything called DrawTextW, only FontHandler::DrawText. I search for DrawTextW and find it in a #define call in the header "WinUser.h"!
//WinUser.h
#define DrawText DrawTextW
Apparently it replaces my DrawText with DrawTextW! How can I stop it from spilling over into my code like that?
It's a minor thing changing my own function's name, but naming conflicts like this seem pretty dangerous and I would really like to know how to avoid them all together.
Cheers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你有几个选择,但都很糟糕。
#undef DrawText
windows.h
。 如果另一个库为您包含它,请不要直接包含它。 相反,请将其包含在单独的 .cpp 文件中,然后该文件可以在其标头中公开您自己的包装器函数。DrawText
。如果可能的话,我通常会选择中间选项。
windows.h
在无数其他方面表现得很糟糕(例如,除非您启用 Microsoft 专有的 C++ 扩展,否则它实际上不会编译),所以我只是像躲避瘟疫一样避免它。 如果我可以帮助的话,它不会包含在我的文件中。 相反,我编写了一个单独的 .cpp 文件来包含它并公开我需要的功能。另外,请随时将其作为错误和/或反馈提交到 connect.microsoft.com。 Windows.h 是一个设计得很糟糕的头文件,如果人们引起微软的注意,他们有一天修复它的机会(微乎其微)。
好消息是
windows.h
是唯一表现如此糟糕的标头。 其他标头通常尝试在宏中添加一些特定于库的名称作为前缀,以避免名称冲突,它们尝试避免为通用名称创建宏,并且尝试避免使用不必要的宏。You have a couple of options, all of which suck.
#undef DrawText
in your own codewindows.h
. If another library includes it for you, don't include that directly. Instead, include it in a separate .cpp file, which can then expose your own wrapper functions in its header.DrawText
.When possible, I usually go for the middle option.
windows.h
behaves badly in countless other ways (for example, it doesn't actually compile unless you enable Microsoft's proprietary C++ extensions), so I simply avoid it like the plague. It doesn't get included in my files if I can help it. Instead, I write a separate .cpp file to contain it and expose the functionality I need.Also, feel free to submit it as a bug and/or feedback on connect.microsoft.com. Windows.h is a criminally badly designed header, and if people draw Microsoft's attention to it, there's a (slim) chance that they might one day fix it.
The good news is that
windows.h
is the only header that behaves this badly. Other headers generally try to prefix their macros with some library-specific name to avoid name collisions, they try to avoid creating macros for common names, and they try avoid using more macros than necessary.这是
#include
ing
的一个不幸的副作用。 假设您实际上并没有在程序中的任何地方使用 Windows 的DrawText()
,那么紧接着使用#undef
是完全安全的:It's an unfortunate side effect of
#include
ing<windows.h>
. Assuming you're not actually using Windows'DrawText()
anywhere in your program, it's perfectly safe to#undef
it immediately after:没有通用的方法可以避免这个问题 - 一旦您使用预处理器 #include 头文件,它就可以重新定义它喜欢的任何名称,并且您对此无能为力。 您可以#undef 该名称,但这假设您知道该名称首先是#define 的。
There is no general way of avoiding this problem - once you #include a header file using the preprocessor it can redefine any name it likes, and there is nothing you can do about it. You can #undef the name, but that assumes you know the name was #defined in the first place.
只需
#undef
您不需要的符号即可。 但请确保包含windows.h
并在包含 SDL 之前执行此操作:Just
#undef
the symbols you don't want. But Make sure that you includewindows.h
and do this before you include SDL: