如何避免与Windows头文件中定义的macros名称冲突?

我有一些C ++代码,包括一个名为CreateDirectory().的方法CreateDirectory(). 以前的代码只使用STL和Boost,但是我最近不得不包含<windows.h>所以我可以查找CSIDL_LOCAL_APPDATA

现在,这个代码:

 filesystem.CreateDirectory(p->Pathname()); // Actually create it... 

不再编译:

 error C2039: 'CreateDirectoryA' : is not a member of ... 

winbase.h对应这个macros

 #ifdef UNICODE #define CreateDirectory CreateDirectoryW #else #define CreateDirectory CreateDirectoryA #endif // !UNICODE 

预处理器正在重新定义我的方法调用。 有没有可能的方法来避免这种命名冲突? 或者我必须重命名我的CreateDirectory()方法?

如果你只是重命名你的CreateDirectory方法,你会更好。 如果你需要使用Windows API,与Windows.h交战是一场失败的战斗。

可以肯定的是,如果你在包含windows.h的时候是一致的 ,这仍然是编译的。 (虽然你可能在其他地方有问题)。

#undef CreateDirectory

您可以创建一个模块,其唯一目的是#include <windows.h>并查找封装在函数中的CSIDL_LOCAL_APPDATA。

 int get_CSIDL_LOCAL_APPDATA(void) { return CSIDL_LOCAL_APPDATA; } 

顺便说一句,做好发生了什么事!

作为开发跨平台代码库的开发人员,这是一个问题。 处理这个问题的唯一方法是

  • 确保windows.h是 – 至少在Windows上构建的 – 通用的。 然后,CreateDirectory宏在每个编译单元中都被定义,并被普遍地用CreateDirectoryW代替。 预编译头文件对此非常理想

或者,如果这是一个不愉快的命题,(这是对我来说)

  • 将windows.h的用法分离到windows特定的实用程序文件中 创建导出基本所需功能的文件。 头文件必须使用兼容的数据类型,但不要依赖于包含windows.h。 cpp实现文件必须(显然)使用windows.h。

如果你的可用性函数需要包含冲突符号的项目头文件,那么下面的模式是必须的:

 #include <windows.h> #ifdef CreateDirectory #undef CreateDirectory #endif // etc #include "some_class_with_CreateDirectory_method.h" // ... 

您将需要显式调用任何Windows API函数的非宏版本,您有#undef'd – CreateDirectoryA或W等

push宏, undef它,再次pop宏:

 #pragma push_macro("CreateDirectory") #undef CreateDirectory void MyClass::CreateDirectory() { // ... } #pragma pop_macro("CreateDirectory") 

请注意,名称冲突通常来自包含某个头文件。 在那之前,像CreateDirectory和GetMessage这样的东西不会被拉进可视化和代码编译没有问题。

你可以将这样一个包含分离到一个包装头文件中,并在其末尾“#undef whatever”。 那么,不管你有什么名字相撞,都会消失。 当然,除非你需要在自己的代码中使用这些宏(是的,所以可能…)

 #pragma push_macro("CreateDirectory") 

如果没有任何工作,而不是重命名,你可以使用自己的命名空间为您的功能。