使用 Visual C++ 编译器在 Windows 上构建库时如何正确设置目标操作系统版本

2024-03-11

我正在使用 Visual C++ 2013 编译器(特别是在 Windows 平台上具有 C++11 功能)构建跨平台库,并使用 CMake(NMake 生成器)作为构建系统。我使用的是 Windows 7。

我的库使用一些仅在 Windows 8/7 中可用的函数/枚举值/结构成员。

我希望能够为 Windows XP、Windows Vista、Windows 7 和 Windows 8/8.1 操作系统版本以及 x86、x64 和 ARM 架构构建库,即不是一个仅针对 Windows XP 并在任何地方都可以工作的构建,而是许多不同的构建针对特定操作系统的构建,因为较新的操作系统版本具有我的库可以提供的更多有用功能。

我的问题是:

  1. 如何告诉编译器针对特定操作系统版本(即 XP、Vista、7、8、8.1 等)?

  2. 如何告诉编译器针对特定架构(即 x86、x64、arm 等)?

  3. 如果我使用仅在 Windows 8/7 中可用的函数/枚举值/结构成员,但构建针对 Windows XP 的库,会发生什么情况?编译器会警告我 Windows XP 上不存在这样的东西吗?或者它实际上可以编译但无法在Windows XP系统上运行?

  4. 如何才能使我的代码在针对 Windows XP 进行编译时跳过 Windows XP 中不存在的内容(Windows 7/8 函数等)?

  5. 当针对不同的操作系统版本时,我使用哪个 Windows SDK 版本重要吗?我似乎已经安装了 8.1、8.0 和 7.1 Windows SDK。即使针对 Windows XP,如果我始终使用最新的 SDK 版本,可以吗?

以下是我找到的一些答案,我不确定这些答案是否正确或完整:

  1. 我只需要设置_WIN32_WINNT and WINVER定义为适合目标系统的值 https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx#macros_for_conditional_declarations就是这样,除此之外我不需要设置任何内容,我的应用程序将在指定的系统(即 Windows XP)上运行。

    • 使用“C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat”设置编译器环境变量时需要使用适当的选项,即“C:\Program Files (x86)\Microsoft Visual Studio 12.0 \VC\vcvarsall.bat amd64" 对于 64 位。
    • 我还需要指定合适的/SUBSYSTEM value https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx到链接器,即/SUBSYSTEM:WINDOWS,5.02 or /SUBSYSTEM:WINDOWS,6.00对于 x64。但有什么区别5.02 and 6.00?为什么两个值指定相同的内容(64 位)?同样适用于5.01 and 6.00,为什么他们都指定32位?我认为 64/32 位有一个值就足够了。

      • 这些值(5.01, 5.02 and 6.00)看起来与平台值相似WINVER来自(1)。除了架构之外,他们还设置目标操作系统吗?但WINVER=502from (1) 用于针对 Windows Server 2003,根据维基百科,Windows Server 2003 发布了 64 位和 32 位版本,但在这里 5.02 严格代表 64 位,这没有意义......
  2. 编译器将无法编译,因为WINVER从 (1) 定义将排除目标操作系统中不存在的函数和内容(Windows 头文件使用该定义来#ifdef事物)。

  3. 我应该#ifdef事物基于WINVER在我自己的代码中,就像 Windows 标头一样,并在需要时提供缺失功能的替代方案。

  4. 不知道。

请注意,我没有使用 Visual Studio IDE,因此告诉我在 IDE 中设置选项 X 有点没有意义。

我来自 Linux 开发,所以 Windows 的东西对我来说有点新鲜。


您对自己问题的回答大部分是正确的。一些澄清和更正:

子系统版本与目标架构正交。什么是/subsystem文档说的是minimumx86 的子系统版本是 5.01,minimumx64 的子系统版本是 5.02。对于控制台和 Windows 应用程序,子系统版本与内部操作系统版本号相同。 5.01 是 x86 Windows XP; 5.02 是 x64 Windows XP。 Windows XP 有两个不同的版本号,因为 x64 Windows XP 的发布晚于 x86 Windows XP。较新的操作系统对于所有体系结构都具有相同的版本号(例如,对于 x86 和 x64,Windows Vista 都是版本 6.0)。

请注意,通过设置子系统版本,您可以限制程序运行的操作系统集。例如,如果您将子系统版本设置为6.2,您的程序将只能在Windows 8及更高版本上运行。如果您尝试在例如上运行该程序Windows 7,它将无法运行。 (对于 DLL 也是如此:如果您有一个 DLL 的目标操作系统比您正在运行的操作系统更新,则加载程序将不会加载该 DLL,至少不会加载代码执行。)

请参阅维基百科的页面“Microsoft Windows 版本列表” https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions获取操作系统版本列表。 Windows XP 是 Visual Studio 2013 支持的最旧的 Windows 版本。

Windows 8 SDK 仅支持Windows Vista 以下版本的软件开发。如果你想设置_WIN32_WINNT or WINVER要针对 Windows XP 进行构建,您需要使用 Windows 7 SDK(Visual Studio 2013 将安装这两个 SDK)。

除非您的程序对于每个目标操作系统都有很大不同,否则构建一个在您想要支持的最旧的操作系统(Windows XP)上运行并延迟加载或动态加载(通过LoadLibrary/GetProcAddress) 您想要从较新的操作系统使用的任何功能(当该功能可用时)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Visual C++ 编译器在 Windows 上构建库时如何正确设置目标操作系统版本 的相关文章

  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 按成员序列化

    我已经实现了template
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • Windows 目录永远不会包含临时文件的非 ASCII 字符?

    在 Windows 上使用 MinGW 7 3 0 由于 Windows 限制 Hunspell 无法从包含非 ASCII 字符的位置加载字典文件 我已经尝试了所有方法 1 现在我将文件复制到没有 ASCII 字符的路径 然后再将其交给 H
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐