我有一些C ++代码包含一个名为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
中的此宏对应:
#ifdef UNICODE
#define CreateDirectory CreateDirectoryW
#else
#define CreateDirectory CreateDirectoryA
#endif // !UNICODE
预处理器正在重新定义我的方法调用。有没有办法避免这种命名冲突?或者我是否必须重命名CreateDirectory()
方法?
答案 0 :(得分:14)
如果您只是重命名CreateDirectory方法,那将会更好。如果你需要使用Windows API,与Windows.h的战斗是一场失败的战斗。
很明显,如果你在包含windows.h时一致,那么仍然会进行编译。 (虽然你可能在其他地方遇到问题)。
答案 1 :(得分:9)
#undef CreateDirectory
答案 2 :(得分:9)
您可以创建一个模块,其唯一目的是#include <windows.h>
并查找包含在函数中的CSIDL_LOCAL_APPDATA。
int get_CSIDL_LOCAL_APPDATA(void)
{
return CSIDL_LOCAL_APPDATA;
}
顺便说一句,为解决发生的事情做得好!
答案 3 :(得分:1)
作为跨平台代码库的开发人员,这是一个问题。处理它的唯一方法是
或者,如果这是一个令人不愉快的主张,(并且它适合我)
如果您的功能需要包含带有冲突符号的项目头文件,则必须使用以下模式:
#include <windows.h>
#ifdef CreateDirectory
#undef CreateDirectory
#endif
// etc
#include "some_class_with_CreateDirectory_method.h"
// ...
然后你需要显式调用你拥有的任何windows api函数的非宏版本#undef'd - CreateDirectoryA或W等。
答案 4 :(得分:0)
push
宏,再次undef
和pop
宏:
#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
// ...
}
#pragma pop_macro("CreateDirectory")
答案 5 :(得分:0)
请注意,名称冲突通常来自包含的某个头文件。在此之前,像CreateDirectory和GetMessage这样的东西没有被提升到可见性,代码编译没有问题。
您可以将这样的包含隔离到包装头文件中,并在其末尾隔离“#undef whatever”。然后,无论你有什么名字冲突都会消失。当然,除非您需要在自己的代码中使用这些宏(是的,所以非常可能......)
答案 6 :(得分:0)
您可以备份CreateDirectory
,然后取消定义它,然后在使用自定义作业完成工作时再次对其进行定义。
#ifdef CreateDirectory
#define CreateDirectory_Backup CreateDirectory
#undef CreateDirectory
#endif
// ...
// Define and use your own CreateDirectory() here.
// ...
#ifdef CreateDirectory_Backup
#define CreateDirectory CreateDirectory_Backup
#undef CreateDirectory_Backup
#endif
答案 7 :(得分:-2)
#pragma push_macro("CreateDirectory")
如果没有任何效果,您可以使用自己的命名空间代替重命名。