C++ WinSDK 头文件编译错误
Posted
技术标签:
【中文标题】C++ WinSDK 头文件编译错误【英文标题】:C++ WinSDK header compilation error 【发布时间】:2012-05-24 13:21:27 【问题描述】:我正在尝试在 Windows 7 的 Visual Studio 2010 中编译程序。我在标记行的 Windows 标头 shlobj.h
中收到编译错误 C2061: syntax error: identifier 'KNOWN_FOLDER_FLAG' :
#if (NTDDI_VERSION >= NTDDI_VISTA)
typedef enum
KF_FLAG_DEFAULT = 0x00000000,
KF_FLAG_CREATE = 0x00008000,
KF_FLAG_DONT_VERIFY = 0x00004000,
KF_FLAG_DONT_UNEXPAND = 0x00002000,
KF_FLAG_NO_ALIAS = 0x00001000,
KF_FLAG_INIT = 0x00000800,
KF_FLAG_DEFAULT_PATH = 0x00000400,
KF_FLAG_NOT_PARENT_RELATIVE = 0x00000200,
KF_FLAG_SIMPLE_IDLIST = 0x00000100,
KF_FLAG_ALIAS_ONLY = 0x80000000,
KNOWN_FOLDER_FLAG;
DEFINE_ENUM_FLAG_OPERATORS(KNOWN_FOLDER_FLAG);
STDAPI SHGetKnownFolderIDList(__in REFKNOWNFOLDERID rfid,
__in DWORD /* KNOWN_FOLDER_FLAG */ dwFlags,
__in_opt HANDLE hToken,
__deref_out PIDLIST_ABSOLUTE *ppidl);
STDAPI SHSetKnownFolderPath(__in REFKNOWNFOLDERID rfid,
__in DWORD /* KNOWN_FOLDER_FLAG */ dwFlags,
__in_opt HANDLE hToken,
__in PCWSTR pszPath);
STDAPI SHGetKnownFolderPath(__in REFKNOWNFOLDERID rfid,
__in DWORD /* KNOWN_FOLDER_FLAG */ dwFlags,
__in_opt HANDLE hToken,
__deref_out PWSTR *ppszPath);
#endif // NTDDI_VISTA
#if (NTDDI_VERSION >= NTDDI_WIN7)
STDAPI SHGetKnownFolderItem(__in REFKNOWNFOLDERID rfid,
__in KNOWN_FOLDER_FLAG flags, <<<ERROR AT THIS LINE
__in_opt HANDLE hToken,
__in REFIID riid,
__deref_out void **ppv);
#endif // NTDDI_WIN7
在我的程序中,版本宏定义如下
#define NTDDI_VERSION NTDDI_WINXP
不编译的原因是什么?
在我看来,我得到错误的部分根本不能编译,但它以某种方式编译。
【问题讨论】:
您如何直接或间接地包含 shlobj.h?一些 Windows 头文件需要通过 windows.h 间接包含才能正确编译。有些可以直接包含,但前提是首先包含 windows.h。在您的代码中,什么使您当前拥有的包含变得必要? 我用的是MFC,估计里面包含shlobj.h文件。 【参考方案1】:只有一个合乎逻辑的结论:由于某种原因,编译这个头文件时NTDDI_VERSION
的扩展不是你想象的那样。
通过搜索 #undef NTDDI_VERSION
并干净构建您的项目尝试进行故障排除(如果您使用的是预编译的标头,可能与此相关)。
【讨论】:
【参考方案2】:编辑:我的答案是在没有向下滚动代码示例的情况下编写的... 您是否确认错误来自定义 SHGetKnownFolderItem 的行?当我遇到这类问题时,我通常会为您的文件创建一个预处理器输出文件,并确认错误实际上来自您期望的位置。可能还有其他一些代码没有得到正确的 NTDDI_VERSION 保护。
Windows SDK 标头旨在允许您为特定版本的 Windows 构建应用程序。
在这种情况下,您要求为 Windows XP 构建应用程序(通过将 NTDDI_VERSION 设置为 NTDDI_WINXP)。那太棒了。但随后您尝试使用 Windows Vista 中引入的枚举 (KNOWN_FOLDER_FLAG)。
您需要做出选择:使用 Windows Vista 版本的 Windows API 构建您的应用程序(通过将 NTDDI_VERSION 设置为 NTDDI_VISTA)或找出另一种分离 Windows Vista 特定功能的方法。
有几种方法可以做到这一点。第一个(也是最棘手的)是使用 Vista 标头构建您的应用程序,然后小心避免在 XP 上使用仅限 Vista 的功能。或者,您可以将 vista 特定功能隔离在另一个源文件/dll 中,并使用 NTDDI_VISTA 编译该文件。然后仅在您不在 XP 上时调用 vista 特定功能。
请注意,如果您将对 SHGetKnownFolderPath 的直接调用添加到您的应用程序中,它将无法在 Windows XP 上运行 - 这是因为该 API 在 XP 上不存在。因此,您必须使用 LoadLibrary/GetProcAddress 技巧来调用 API。
【讨论】:
这并不能回答 Op 的问题。他定义了 NTDDI_XP,因此 NTDDI_VISTA 垃圾不包括在内,但是在同一个头文件中,NTDDI_WIN7(应该大于 NTDDI_VISTA 并取决于它)被包括在内以进行编译。【参考方案3】:改变
定义 NTDDI_VERSION NTDDI_WINXP
到
定义 NTDDI_VERSION NTDDI_VISTA
在声明 ShlObj 标头之前 在 Windows 10 中工作正常
【讨论】:
以上是关于C++ WinSDK 头文件编译错误的主要内容,如果未能解决你的问题,请参考以下文章