通过C++跨平台的预编译宏来区分不同的操作系统:Win32/Win64/Unix/Linux/MacOS

因为 C++ 具有跨平台的特性,所以有些需求一套代码就多端使用,比如我最近在学习的 OpenGL ES。

但是,不同平台还是具有一定差异性,所以我们首先得判断出是什么平台? 比如 iOS 系统和 Android 系统。

那么如何判断呢?我们接着往下看!

要检查 C 或 C 代码中主机的操作系统,我们需要检查编译器(GNU GCC 或 G )定义的宏。 例如,在 Windows 平台上,编译器定义了一个名为 _WIN32 的特殊宏。 因此,如果定义了宏 _WIN32,我们就在 Windows 上。 同样,其他操作系统也有编译器定义的特定宏。

C++ 编译器预定义了某些全局标识符,称为 manifest constants 。大多数全局标识符以两个下划线 (__) 开头和结尾。

检查 Windows 操作系统的示例:

 
  1. #ifdef _WIN32
  2. printf("You have Windows Operating System");
  3. #endif

1.1 宏定义列表

以下是基于操作系统定义的宏列表:

操作系统宏定义说明
Windows 32 bit + 64 bit_WIN32for all Windows OS
Windows 64 bit_WIN64Only for 64 bit Windows
Apple__APPLE__for all Apple OS
Apple__MACH__alternative to above
iOS embeddedTARGET_OS_EMBEDDEDinclude TargetConditionals.h
iOS stimulatorTARGET_IPHONE_SIMULATORinclude TargetConditionals.h
iPhoneTARGET_OS_IPHONEinclude TargetConditionals.h
MacOSTARGET_OS_MACinclude TargetConditionals.h
Android__ANDROID__subset of linux
Unix based OS__unix__
Linux__linux__subset of unix
POSIX based_POSIX_VERSIONWindows with Cygwin
Solaris__sun
HP UX__hpux
BSDBSDall BSD flavors
DragonFly BSD__DragonFly__
FreeBSD__FreeBSD__
NetBSD__NetBSD__
OpenBSD__OpenBSD__

请注意,宏对 GNU GCC 和 G++ 有效,并且可能因其他编译器而异。 我们将通过一些基本示例,并探讨这些功能在现实生活中的使用。

关于更多的宏定义可以参考下面的两个链接:

  • Predefined Macros
  • Pre-defined Compiler Macros

1.2 示例: 检测 64 位 Windows 操作系统或 32 位 Windows 操作系统

在下面的示例中,我们专注于检测我们正在运行的 Windows 的风格,它可以是 64 位或 32 位。对于 Windows,我们的表格将是:

操作系统宏定义
Windows OS 32 bit + 64 bit_WIN32
Windows OS 64 bit_WIN64

由于 _WIN32 在 32 位和 64 位 Windows 操作系统中都存在,
所以我们需要先检查 _WIN32 的存在以确认它是 Windows 操作系统,
然后再检查 _WIN64 的存在以确认它是否是 64 位 Windows 操作系统或 32 位 Windows 操作系统。

以下是检查您的 Windows 操作系统的代码:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. #ifdef _WIN32 // Includes both 32 bit and 64 bit
  5. #ifdef _WIN64
  6. printf("Windows 64 bit\n");
  7. #else
  8. printf("Windows 32 bit\n");
  9. #endif
  10. #else
  11. printf("Not a Windows OS\n");
  12. #endif
  13. return 0;
  14. }

运行输出

  1. Windows 32 bit

1.3 示例:检测苹果操作系统是MacOS 还是 iPhone

在此示例中,我们使用 Apple OS 的宏来检测正在使用的 Apple OS,如 MacOS 或 iPhone

  1. #include <stdio.h>
  2. int main()
  3. {
  4. #if __APPLE__
  5. #include "TargetConditionals.h"
  6. #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
  7. printf("iPhone stimulator\n");
  8. #elif TARGET_OS_IPHONE
  9. printf("iPhone\n");
  10. #elif TARGET_OS_MAC
  11. printf("MacOS\n");
  12. #else
  13. printf("Other Apple OS\n");
  14. #endif
  15. #else
  16. printf("Not an Apple OS\n");
  17. #endif
  18. return 0;
  19. }

运行输出

  1. MacOS

1.4 普通示例

  1. #include <stdio.h>
  2. int main() {
  3. #ifdef _WIN32
  4. printf("Windows\n");
  5. #elif __linux__
  6. printf("Linux\n");
  7. #elif __unix__
  8. printf("Other unix OS\n");
  9. #else
  10. printf("Unidentified OS\n");
  11. #endif
  12. return 0;
  13. }

1.5 作用

凭借检测语言(在我们的案例中为 C 和 C++)中的操作系统的能力,我们可以编写一个跨平台代码,通过分离平台相关代码来在所有平台上运行。

  1. #include <stdio.h>
  2. int main()
  3. {
  4. #if __APPLE__
  5. // apple specific code
  6. #elif _WIN32
  7. // windows specific code
  8. #elif __LINUX__
  9. // linux specific code
  10. #elif BSD
  11. // BSD specific code
  12. #else
  13. // general code or warning
  14. #endif
  15. // general code
  16. return 0;
  17. }

同时,我们可以编写针对特定平台优化的代码。

例如,一个函数调用可能在所有平台上都受支持,但我们可以针对特定平台(例如 Linux)对其进行大幅优化,但是这个新代码会在其他平台上引发错误。 在这种情况下,我们可以使用宏来检测它是否是 Linux,对于这种情况,我们可以轻松地使用其他替代优化代码。

例如:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. #if __linux__
  5. // linux optimized code (will fail in other platforms)
  6. #else
  7. // general code for all platforms
  8. #endif
  9. // general code
  10. return 0;
  11. }

2.1 一个简单的判断

  1. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
  2. //define something for Windows (32-bit and 64-bit, this part is common)
  3. #ifdef _WIN64
  4. //define something for Windows (64-bit only)
  5. #else
  6. //define something for Windows (32-bit only)
  7. #endif
  8. #elif __APPLE__
  9. #include <TargetConditionals.h>
  10. #if TARGET_IPHONE_SIMULATOR
  11. // iOS, tvOS, or watchOS Simulator
  12. #elif TARGET_OS_MACCATALYST
  13. // Mac's Catalyst (ports iOS API into Mac, like UIKit).
  14. #elif TARGET_OS_IPHONE
  15. // iOS, tvOS, or watchOS device
  16. #elif TARGET_OS_MAC
  17. // Other kinds of Apple platforms
  18. #else
  19. # error "Unknown Apple platform"
  20. #endif
  21. #elif __linux__
  22. // linux
  23. #elif __unix__ // all unices not caught above
  24. // Unix
  25. #elif defined(_POSIX_VERSION)
  26. // POSIX
  27. #else
  28. # error "Unknown compiler"
  29. #endif

2.2 优秀的 googletest 的示例

googletest/googletest/include/gtest/internal/gtest-port-arch.h at main · google/googletest · GitHub

  1. // Copyright 2015, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. // The Google C++ Testing and Mocking Framework (Google Test)
  30. //
  31. // This header file defines the GTEST_OS_* macro.
  32. // It is separate from gtest-port.h so that custom/gtest-port.h can include it.
  33. #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
  34. #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
  35. // Determines the platform on which Google Test is compiled.
  36. #ifdef __CYGWIN__
  37. #define GTEST_OS_CYGWIN 1
  38. #elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
  39. #define GTEST_OS_WINDOWS_MINGW 1
  40. #define GTEST_OS_WINDOWS 1
  41. #elif defined _WIN32
  42. #define GTEST_OS_WINDOWS 1
  43. #ifdef _WIN32_WCE
  44. #define GTEST_OS_WINDOWS_MOBILE 1
  45. #elif defined(WINAPI_FAMILY)
  46. #include <winapifamily.h>
  47. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  48. #define GTEST_OS_WINDOWS_DESKTOP 1
  49. #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
  50. #define GTEST_OS_WINDOWS_PHONE 1
  51. #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
  52. #define GTEST_OS_WINDOWS_RT 1
  53. #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
  54. #define GTEST_OS_WINDOWS_PHONE 1
  55. #define GTEST_OS_WINDOWS_TV_TITLE 1
  56. #else
  57. // WINAPI_FAMILY defined but no known partition matched.
  58. // Default to desktop.
  59. #define GTEST_OS_WINDOWS_DESKTOP 1
  60. #endif
  61. #else
  62. #define GTEST_OS_WINDOWS_DESKTOP 1
  63. #endif // _WIN32_WCE
  64. #elif defined __OS2__
  65. #define GTEST_OS_OS2 1
  66. #elif defined __APPLE__
  67. #define GTEST_OS_MAC 1
  68. #include <TargetConditionals.h>
  69. #if TARGET_OS_IPHONE
  70. #define GTEST_OS_IOS 1
  71. #endif
  72. #elif defined __DragonFly__
  73. #define GTEST_OS_DRAGONFLY 1
  74. #elif defined __FreeBSD__
  75. #define GTEST_OS_FREEBSD 1
  76. #elif defined __Fuchsia__
  77. #define GTEST_OS_FUCHSIA 1
  78. #elif defined(__GNU__)
  79. #define GTEST_OS_GNU_HURD 1
  80. #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
  81. #define GTEST_OS_GNU_KFREEBSD 1
  82. #elif defined __linux__
  83. #define GTEST_OS_LINUX 1
  84. #if defined __ANDROID__
  85. #define GTEST_OS_LINUX_ANDROID 1
  86. #endif
  87. #elif defined __MVS__
  88. #define GTEST_OS_ZOS 1
  89. #elif defined(__sun) && defined(__SVR4)
  90. #define GTEST_OS_SOLARIS 1
  91. #elif defined(_AIX)
  92. #define GTEST_OS_AIX 1
  93. #elif defined(__hpux)
  94. #define GTEST_OS_HPUX 1
  95. #elif defined __native_client__
  96. #define GTEST_OS_NACL 1
  97. #elif defined __NetBSD__
  98. #define GTEST_OS_NETBSD 1
  99. #elif defined __OpenBSD__
  100. #define GTEST_OS_OPENBSD 1
  101. #elif defined __QNX__
  102. #define GTEST_OS_QNX 1
  103. #elif defined(__HAIKU__)
  104. #define GTEST_OS_HAIKU 1
  105. #elif defined ESP8266
  106. #define GTEST_OS_ESP8266 1
  107. #elif defined ESP32
  108. #define GTEST_OS_ESP32 1
  109. #elif defined(__XTENSA__)
  110. #define GTEST_OS_XTENSA 1
  111. #endif // __CYGWIN__
  112. #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨境云专线:构建高速、安全的全球业务网络

在企业出海加速的背景下&#xff0c;越来越多的企业需要在全球范围内部署业务&#xff0c;特别是在多个国家和地区之间进行数据传输。然而&#xff0c;跨境网络连接常常面临带宽不足、延迟高、数据安全性差等问题&#xff0c;这给企业的业务运营带来了巨大挑战。为了解决这些问…

分布式——BASE理论

简单来说&#xff1a; BASE&#xff08;Basically Available、Soft state、Eventual consistency&#xff09;是基于CAP理论逐步演化而来的&#xff0c;核心思想是即便不能达到强一致性&#xff08;Strong consistency&#xff09;&#xff0c;也可以根据应用特点采用适当的方…

UE5.4 PCG 获取地形Layer

使用AttributeFilter&#xff1a;属性过滤器 节点 设置地形Layer名称和权重 效果&#xff1a;

使用wordpress搭建简易的信息查询系统

背景 当前有这样的一个需求&#xff0c;要实现让客户能够自助登录系统查询一些个人的信息&#xff0c;市面上没有特别符合我的需求的产品&#xff0c;经过一段时间的研究&#xff0c;想出了一个用wordpress实现简易信息查询系统&#xff0c;有两种方式。 方式一&#xff1a;使…

EasyUI弹出框行编辑,通过下拉框实现内容联动

EasyUI弹出框行编辑&#xff0c;通过下拉框实现内容联动 需求 实现用户支付方式配置&#xff0c;当弹出框加载出来的时候&#xff0c;显示用户现有的支付方式&#xff0c;datagrid的第一列为conbobox,下来选择之后实现后面的数据直接填充&#xff1b; 点击新增&#xff1a;新…

ssm079基于SSM框架云趣科技客户管理系统+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;客户管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本客户管理系统就是在这…

PICO+Unity 用手柄点击UI界面

如果UI要跟随头显&#xff0c;可将Canvas放置到XR Origin->Camera Offset->Main Camera下 1.Canvas添加TrackedDeviceGraphicRaycaster组件 2.EventSystem移动默认的Standard Input Module&#xff0c;添加XRUIInputModule组件 3.&#xff08;可选&#xff09;设置射线可…

apt镜像源制作-ubuntu22.04

# 安装必要的软件 sudo apt-get install -y apt-mirror # 编辑/etc/apt/mirror.list,添加以下内容 set base_path /var/spool/apt-mirror # 指定要镜像的Ubuntu发布和组件-null dir jammy-updates main restricted universe multiverse # 镜像的Ubuntu发布和组件的URL-n…

springboot初体验

目录 环境 controller 修改端口号 更改banner图标 运行结果 最核心的:自动装配 环境 jdk17springboot3.3.5maven3.8.2 controller controller层和启动类同级 package com.example.demo.controller; ​ import org.springframework.web.bind.annotation.RequestMapping;…

Q:警告无法解释导入PIL Pylance(reportMisssingIMports)

问题显示&#xff1a; 解决方法&#xff1a; 1.确认安装 Pillow&#xff1a;在 VS Code 的终端中运行以下命令&#xff0c;以确保环境中安装了 Pillow pip install pillow2.选择正确的解释器&#xff1a;在 VS Code 中&#xff0c;按下 CtrlShiftP&#xff0c;输入并选择 “P…

python中常见的8种数据结构之一数组的应用

在Python中&#xff0c;数组是一种常见的数据结构&#xff0c;用于存储一系列相同类型的元素。在实际应用中&#xff0c;数组可以用于解决各种问题。 以下是数组在Python中的一些常见应用&#xff1a; 1. 存储和访问数据&#xff1a;数组可以用于存储和访问一组数据。可以通过…

网络安全——下载并在kali虚拟机上启动Cobalt Strike

目录 一、下载 二、上传文件到kali虚拟机 三、启动服务端 四、启动客户端 一、下载 CobaltStrike4.8汉化版带插件-CSDN博客 下载并解压后 二、上传文件到kali虚拟机 1、打开并运行kali虚拟机&#xff0c;查看kali的ip地址 2、打开xshell&#xff0c;新建连接&#xff0c;连…

用 Python 从零开始创建神经网络(四):激活函数(Activation Functions)

激活函数&#xff08;Activation Functions&#xff09; 引言1. 激活函数的种类a. 阶跃激活功能b. 线性激活函数c. Sigmoid激活函数d. ReLU 激活函数e. more 2. 为什么使用激活函数3. 隐藏层的线性激活4. 一对神经元的 ReLU 激活5. 在隐蔽层中激活 ReLU6. ReLU 激活函数代码7. …

22.oop-strust与class

OOP是什么&#xff1a;oop 是面向对象编程,面向对象编程是一种计算机编程架构, OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或 对象组、合而成。 OOP有什么特性&#xff1a; 1、封装性&#xff1a;也称为信息隐藏&#xff0c;就是将一个类的使用和实现分开…

【Linux】ubuntu安装图形化界面步骤

一、ubuntu 安装桌面环境 1、更新软件包列表&#xff08;命令↓&#xff09; sudo apt update 2、安装桌面环境GNOME&#xff08;命令↓&#xff09; sudo apt install ubuntu-desktop 3、安装完成后需要重启服务器&#xff08;服务器重启命令↓&#xff09; sudo reboot 二、…

【Android】轮播图——Banner

引言 Banner轮播图是一种在网页和移动应用界面设计中常见的元素&#xff0c;主要用于在一个固定的区域内自动或手动切换一系列图片&#xff0c;以展示不同的内容或信息。这个控件在软件当中经常看到&#xff0c;商品促销、热门歌单、头像新闻等等。它不同于ViewPgaer在于无需手…

Vue2 doc、excel、pdf、ppt、txt、图片以及视频等在线预览

Vue2 doc、excel、pdf、ppt、txt、图片等在线预览 安装使用目录结构直接上代码src\components\FileView\doc\index.vuesrc\components\FileView\excel\index.vuesrc\components\FileView\img\index.vuesrc\components\FileView\pdf\index.vuesrc\components\FileView\ppt\index…

[OpenGL]使用OpenGL实现硬阴影效果

一、简介 本文介绍了如何使用OpenGL实现硬阴影效果&#xff0c;并在最后给出了全部的代码。本文基于[OpenGL]渲染Shadow Map&#xff0c;实现硬阴影的流程如下&#xff1a; 首先&#xff0c;以光源为视角&#xff0c;渲染场景的深度图&#xff0c;将light space中的深度图存储…

微服务是什么 SpringCloud是什么

微服务是什么 SpringCloud是什么 一、微服务概述二、微服务架构三、单体架构四、分布式架构五、SpringCloud概述六、SpringBoot和 SpringCloud的区别与联系七、SpringCloud版本选择 一、微服务概述 微服务&#xff08;MicroServices&#xff09;最初是由 Martin Fowler 于 2014…

K8S node节点没有相应的pod镜像运行故障处理办法

查看从节点状态 kubectl describe node k8s-node1以下是报错提示 解决办法 需要处理node1节点上的磁盘空间&#xff0c;磁盘空间需要在85%内 处理后的状态 处理正常