【问题标题】:Do per-project preprocessor definitions override inherited values?每个项目的预处理器定义会覆盖继承的值吗?
【发布时间】:2016-01-14 15:01:32
【问题描述】:

我想设置_WIN32_WINNT = 0x0601(Windows 7),但我发现它似乎仍然停留在0x0502 - 某些 WinAPI 函数不可用,并且 intillisense 在重建后将值显示为 0x502。

我的预处理器定义窗口如下所示:

我们有一个用于所有项目的标准属性文件,我不想只为一个模块修改它...这会导致问题吗?

如果我手动重新定义 StdAfx.h 文件中的值,它似乎可以工作,但我有点担心这样做:

#ifdef _WIN32_WINNT
    #undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x601

【问题讨论】:

  • 在命令行定义预处理器符号与使用#define Directive 相同。不能重新定义预处理器符号(除非两个定义在词法上 - 或在 Visual Studio 的情况下在语法上 - 相同)。我希望命令行上的预处理器符号定义遵循相同的规则。换句话说:您对预处理器定义的使用是未定义的。如果_WIN32_WINNT 在所有编译单元中不完全相同,请不要将其添加到用于所有编译单元的公共属性表中。

标签: visual-studio winapi visual-c++


【解决方案1】:

如果您希望控制首先选择哪一组预处理器定义,您可以查看属性表 (.props/.vsprops)。您可以使用它指定评估顺序,因此您的覆盖 .props 文件可以在默认道具之前使用。

例如,我有一个产品也打算在 Windows XP 上运行,所以 _WIN32_WINNT 需要为 0x0500。我为我的 Vista++ 项目添加了一个道具,将 _WIN32_WINNT 指定为 0x0600。我将其标记为在默认道具文件之前进行评估。这种方法也适用于无法在 VS 2013 中编译的 MFC 项目,除非 WINVER >= 0x0501。

这不是一个完美的解决方案,但除了使用 undef 和 define 之外,这可能是最好的选择。

【讨论】:

    【解决方案2】:

    每个项目的预处理器定义会覆盖继承的值吗?

    不,他们没有。

    Visual Studio 将它们命名为继承是一种误导,就好像它们可以被覆盖一样。发生的情况是,所有以 WIN32 开头的定义都被简单地制成一个列表,以这种方式传递给编译器: /DWIN32 /D_WIN32_WINNT=0x0601 ... /D_WIN32_WINNT=0x0502 /D_MDCS /D_AFXDLL。正如您所看到的,您尝试为_WIN32_WINNT 设置的任何内容都是“继承的”。 这真的很愚蠢,他们应该颠倒顺序或定义,这样继承的值不会覆盖您在项目中设置的值。

    避免此错误的一种可能解决方案是取消选中有问题的“继承”并在覆盖之前手动放置继承的值:

    _WINDOWS
    %(PreprocessorDefinitions)
    _WIN32_WINNT=0x0601
    

    这是它在我的项目中的样子:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 2019-06-29
      相关资源
      最近更新 更多