【问题标题】:'windows.h', what about other platforms?'windows.h',其他平台呢?
【发布时间】:2020-08-22 23:19:01
【问题描述】:

我在 Windows 上使用 Visual Studio,我有一个名为 windows.h 的头文件,这当然可以让我访问 win32 API。

但是当我尝试使用其他平台 API 时,例如 linux API。我没有找到任何具有该名称的头文件,这意味着我不能使用除 windows 之外的任何其他 OS API,

现在这里的问题是:如果我不想制作一个跨平台程序怎么办?当我没有对其 API 的适当访问权限时,我尝试进行一些研究,但无法得到任何问题的答案,这现在真的让我很困扰,所以更具体地说,这些是我的问题:

1- 为什么我只能在所有其他操作系统中使用 Windows API? 是因为我在 Windows 上编码,所以如果我在“其他地方”编码,它会有所不同吗? 还是与编译器本身有关?

2- 如果我想使用另一个 API,我必须使用外部库吗?如果是这种情况,c++ 跨平台的标准库如何,我的意思是如果它是跨平台的,那么应该存在库提供的其他平台特定的头文件吗?

【问题讨论】:

  • "如果我不想做一个跨平台程序怎么办?" - 在这种情况下,您会回避 windows.h 和任何其他操作系统特定的 API。或者,如果您必须在应用程序的某些角落使用一些特定于操作系统的代码,那么对于您支持的每个平台,您将有不同的这些位实现 - 可能包含在一些自定义函数中,其中包含大量 @987654323 @ 或有多个实现文件,您的构建系统在编译时为平台选择正确的一个。但是,请尽量远离特定于平台的 API,并使其更加便携和快乐。
  • 有些库(如Qt)可以为您抽象出所有平台差异,并让您使用单个 API 编写跨平台 GUI 应用程序。另一个更底层的例子是SFML

标签: c++ stl cross-platform


【解决方案1】:

我在 Windows 上使用 Visual Studio,我有一个名为 windows.h 的头文件,这当然可以让我访问 win32 API。

严格来说windows.h 是一种元标题。 windows.h 中定义了一些重要的宏、标记和​​符号,但它也引入了 很多 其他标题。如果您查看每个 Win32 API 函数的参考手册,它会告诉您该函数是在哪个标头中声明的。例如,让我们看看 CreateFileA: 在参考手册的底部,您会发现:

要求


支持的最低客户端 Windows XP [仅限桌面应用]


支持的最低服务器 Windows Server 2003 [仅限桌面应用]


目标平台窗口


标题fileapi.h(包括Windows.h


库 Kernel32.lib


DLL Kernel32.dll

这告诉我们,CreateFileA 实际上是在fileapi.h 中声明的,并且是从kernel32.dll 系统库中导出的。

但是当我尝试使用 linux API 等其他平台 API 时 例子。

也就是说,因为没有 linux.h API 标头(如果您在 Linux 开发系统中搜索名为 linux.h 的文件,您会发现很多,但系统不使用这些文件级 API)。

原因是,Linux 没有自己的专有 API,但遵循操作系统 API 的 POSIX 行业标准和 Single Unix Specification maintained by the Open Group p>

当然有特定于 Linux 的 API,但您可以放心地忽略它们以进行“常规”应用程序开发;如果你在做低级的事情,比如编写 C 运行时库或自定义内存分配器,则需要这些。

作为开发人员,您最感兴趣的是第 2 节(调用操作系统内核 = 系统调用)和第 3 节(库函数)中的手册页。 https://linux.die.net/man/

等同于CreateFileA 的POSIX 将是open,您可以在第2 节中找到它:https://linux.die.net/man/2/open(或creat 系统调用,由于遗留原因而存在,但没有人使用它(或应该使用它) )。

如果您查看 open 的联机帮助页,它会告诉您

open(2) - Linux 手册页


名称

打开,创建 - 打开并可能创建文件或设备

概要

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);

这告诉你,为了使用open,你需要包含sys/types.hsys/stat.hfcntl.h。与 Windows 不同,没有包含所有内容的包罗万象的标题。这样做的原因是,出于向后和交叉兼容性的原因可以通过在包含标头之前将某些宏设置为特定值来配置标头公开的内容。这些在feature_test_macros(7) 中进行了解释,对于它们应用的功能,也在相应的手册页中提到。

我没有找到任何具有该名称的头文件,这意味着 我不能使用除 windows 之外的任何其他操作系统 API,

你找不到,不代表它不存在。

现在这里的问题是:如果我不想做一个跨平台程序怎么办?

然后你将所有平台特定的东西写入一个单独的.c 文件,该文件封装了操作系统的东西。

当我没有对其 API 的适当访问权限时

嗯,你会的。

1- 为什么我只能使用所有其他操作系统中的 windows API?

因为你不能。 Windows.h 仅适用于 Windows 系统。

2- 如果我想使用另一个 API,我必须使用外部库吗?

那你就用它吧。

请记住,在 Linux 中,图形环境不是主操作系统的一部分。它实际上是一个在系统启动时自动启动的常规程序。因此,您不会在上述手册页中找到相关文档。

Linux 的默认图形环境是 Xorg(X11 显示系统的开放实现)。还有 Wayland,但经过 10 多年的开发,它的支持仍然很差,还有很多不足之处。

如果您想将 X11 编程到与 Win32 相同的级别,则必须处理 XlibXcb。然而直接 X11 编程是相当乏味的。您可能想要使用一些不错的应用程序框架,例如Qt 或 GTK。 Qt 本身是一个跨平台框架,所以如果你限制自己只使用 Qt 功能,那么你的程序将完全跨平台而不需要额外的努力。如果您想在 GPU 上制作 3D 图形,请使用跨平台 API OpenGL 或 Vulkan。

【讨论】:

    【解决方案2】:

    但是当我尝试使用其他平台 API 时,例如 linux API。我没有找到任何同名的头文件

    系统 API 没有名为 &lt;linux&gt; 的标头。 POSIX 操作系统规范(Linux 符合)列出了几个头文件,其中包含您可能在该系统上的 windows.h 中找到的功能。 POSIX 规范与 C 标准库重叠,C 标准库实现也提供了 POSIX 特定的头文件。有关标头的完整列表,请参阅 Linux 手册或 POSIX 规范。

    如果我想使用另一个 [系统] API 怎么办

    您至少需要该 API 的头文件才能编译调用它们的程序。此外,您需要图书馆档案才能链接您的程序。你需要告诉编译器你的目标是哪个系统。默认情况下,所有编译器都假定您以运行编译器的系统为目标。您需要查阅编译器的文档,了解是否可以进行交叉编译以及如何进行。

    或者更简单的方法:在提供 API 的系统上编译。标头可能需要单独安装。

    ...c++中的标准库如何跨平台

    每个系统都有自己的标准库。标准库的一些实现是跨平台的,但不是全部。例如,作为 GNU 项目一部分的标准库,并且是 Linux 中的默认标准库,libstdc++ 在包括 Windows 在内的许多平台上都可用。相比之下,Msvc 标准库仅在 Windows 上可用。

    【讨论】:

      【解决方案3】:
      1. Wikipedia 关于windows.h 库说:

      windows.h 是用于 C 和 C++ 的 Windows 特定头文件 包含所有声明的编程语言 Windows API 中的函数,Windows 使用的所有常用宏 程序员,以及各种函数使用的所有数据类型和 子系统。


      1. Linux 不像 Windows 那样提供默认的窗口管理 API,因此如果您正在编写图形应用程序,那么您还需要选择一个窗口库。

      【讨论】:

      • 所以 windows.h 只能在 windows 上使用,但是根据你的解释,我仍然不明白标准库是如何跨平台的
      • @Ronaldjoe 查看@john的回答,标准库接口的实现不是跨平台的
      • @Ronaldjoe windows.h 不是标准库的一部分。标准库隐藏了平台依赖并公开了一个接口,该接口保证在支持标准库的所有平台之间保持一致。
      【解决方案4】:

      第一部分的答案是肯定的。您只能使用 Windows API,因为您是在 Windows 上编程。但是,您可以在 Windows 上运行 Linux。一个名为 Windows Subsystem for Linux 的 Microsoft 产品允许您这样做。但是即使你这样做了,你也不会找到一个名为 linux.h 的头文件,它比这更复杂。还有一个产品(我相信称为 WINE)可以让您在 Linux 上使用 Windows API,尽管我认为它存在一些问题。

      标准库接口是跨平台的,但它的实现肯定不是。它通过抽象出操作系统特定的功能来做到这一点。如果您查看该库是如何在不同平台上实现的,您肯定会发现很多差异。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多