21

我有一些 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()方法?

4

8 回答 8

15

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

顺便说一句,如果您始终如一地包含 windows.h,那么它仍将被编译。(尽管您在其他地方可能会遇到问题)。

于 2010-02-23T21:09:34.947 回答
10

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

int get_CSIDL_LOCAL_APPDATA(void)
{
    return CSIDL_LOCAL_APPDATA;
}

顺便说一句,很好地解决了发生的事情!

于 2010-02-23T21:24:01.110 回答
9

#undef 创建目录

于 2010-02-23T21:10:07.720 回答
3

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

  • 确保 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 等。

于 2010-02-24T08:00:46.950 回答
1

push宏,undef它和pop宏再次:

#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
 // ...
}
#pragma pop_macro("CreateDirectory")
于 2017-01-14T16:23:09.100 回答
1

您可以备份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
于 2018-08-13T08:34:28.807 回答
0

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

您可以将这样的包含隔离到一个包装头文件中,并在其末尾添加“#undef whatever”。然后,无论你有什么名字冲突都会消失。当然,除非您需要在自己的代码中使用这些宏(是的,很有可能......)

于 2017-02-10T16:21:50.810 回答
-2
#pragma push_macro("CreateDirectory")

如果没有任何效果,您可以使用自己的命名空间来代替重命名函数。

于 2010-02-23T22:11:12.500 回答