【问题标题】:C++ compile time macros to detect windows osC++ 编译时宏来检测 Windows 操作系统
【发布时间】:2012-04-24 02:51:08
【问题描述】:

是否存在任何 C++ 编译时宏来检测代码正在哪个 Windows 操作系统上编译。我基本上只想在Win7上支持某些功能。所以我有兴趣做这样的事情

#if <os_macro> = WIN7
  // This function would do something valid only on Win7 builds.
  bool myfunction {
        // do something here
  }
#else
  // This function would typically return false, since its not supported on OS below win7
  bool myfunction {
       return false;
  }
#endif 

还有其他更好的方法吗?

【问题讨论】:

  • 它在哪个操作系统上编译有什么帮助?它不需要知道它在哪个操作系统上运行吗?
  • 在 Visual Studio 中,您可以使用 #ifdef WIN32#ifdef _WINDOWS 进行跨平台。如果您只想要 Windows 版本,您通常会自己定义 WINVER。对于 Windows 7 #define WINVER 0x0601

标签: c++ windows windows-7 header preprocessor-directive


【解决方案1】:

有些事情确实需要在编译时知道哪个操作系统版本。

例如import "winhttp.dll"会在Windows 7下编译,但在Windows 10下会导致编译时错误(C1083)。

但是如果你切换到import "winhttpcom.dll"。它可以在 Windows 10 下编译,但在 Windows 7 下会失败。

所以这里需要一个 OS 宏来导入合适的 dll。

【讨论】:

  • 如何解决这个问题?
【解决方案2】:

在我的情况下,对于想要在 Visual Studio (2017) 下的 CONSOLE 和 WIN32 App 之间以不同方式编译/包含的人来说,我的两分钱。

您使用向导创建控制台应用程序,您将拥有:

WIN32;_DEBUG;_CONSOLE;%(预处理器定义)

在:

如果您使用 win32 GUI App:

的向导

WIN32;_DEBUG;_WINDOWS;%(预处理器定义) 所以没有_CONSOLE。

所以你可以写:

#ifdef _CONSOLE
// for Console
#else
// for GUI


#endif // _CONSOLE



int main()
{
#ifdef _CONSOLE
    // for Console
#else
    // for GUI


#endif // _CONSOLE


    return 0;
}

【讨论】:

    【解决方案3】:

    编译的操作系统并不是那么重要;更重要的是代码在其上运行的操作系统,您显然无法在编译时检测到。但是,如果您希望您的代码在旧版本的 Windows 上运行,您可以将 WINVER and _WIN32_WINNT 设置为某些值,这将导致新功能不可用等(只需搜索 Windows 头文件,以了解这些宏在何处进行测试以获得一个想法)。

    要在运行时测试功能,请使用GetProcAddress(如果它位于较新的 DLL 中,还可能使用LoadLibrary)来测试该功能是否可用。如果是,就调用它,如果不是,不要。

    如果您想检测编译器版本等,另请参阅 Visual Studio 编译器使用的predefined macros

    【讨论】:

    • 基本上我应该可以说,这是一个有一定能力的Win7版本,而这是一个没有能力的WinXP版本。在这里,我将定义能力应该是什么。
    • 为什么要单独构建?为什么不根据运行的操作系统构建一个行为不同的版本?
    【解决方案4】:

    有一套标准windows header macros告诉你操作系统的确切版本

    【讨论】:

    • 这些宏如何进行比较?我尝试像这样使用 Winver #if WINVER >= _WIN32_WINNT_WIN7,但效果不佳。
    【解决方案5】:

    对于初学者来说,至少对于 MS VC++、WIN32、_WIN32 和 _WIN32_WINNT。除非您需要在编译时对其进行控制,否则您可能会考虑使用 GetVersionEx 之类的东西在运行时进行检测,因此相同的构建可以在旧版本上运行,但会在新功能可用时利用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-14
      • 2011-05-20
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      相关资源
      最近更新 更多