我正在学习c++,我刚刚开始学习Qt的一些功能来编写GUI程序。我问了自己以下问题:

c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络进行通信的方式(我承认我也不完全理解api),它是如何通过c++本身编写的库突然获得这些功能的?在我看来,这一切都是可怕的循环。你能在这些库中找到哪些c++指令?

我知道这个问题对一个有经验的软件开发人员来说似乎微不足道,但我已经研究了几个小时,没有找到任何直接的回答。这已经到了我无法理解Qt教程的地步,因为库的存在对我来说是不可理解的。


当前回答

C和c++有两个属性,允许OP所谈论的所有这些可扩展性。

C和c++可以访问内存 C和c++可以调用非C或c++语言中的汇编代码。

在内核或基本的非保护模式平台中,外围设备(如串口或磁盘驱动器)以与RAM相同的方式映射到内存映射中。内存是一系列的开关,翻转外围设备的开关(比如串口或磁盘驱动器)可以让外围设备做一些有用的事情。

在保护模式操作系统中,当用户希望从用户空间访问内核时(比如写入文件系统或在屏幕上绘制像素),需要进行系统调用。C语言没有指令来进行系统调用,但是C语言可以调用汇编代码来触发正确的系统调用,这就是为什么C代码可以与内核对话。

为了使特定平台的编程更容易,系统调用被包装在更复杂的函数中,这些函数可以在自己的程序中执行一些有用的函数。可以直接调用系统调用(使用汇编程序),但是使用平台提供的一个包装器函数可能更容易。

还有另一层API比系统调用有用得多。以malloc为例。这不仅会调用系统来获取大块的内存,而且还会通过对正在发生的事情进行所有簿记来管理这些内存。

Win32 api用一个公共平台小部件集包装了一些图形功能。Qt更进一步,以跨平台的方式包装了Win32(或X Windows) API。

从根本上讲,C编译器将C代码转换为机器代码,由于计算机被设计为使用机器代码,所以你应该期望C能够完成计算机所能完成的大部分工作。包装器库所做的一切都是为您做繁重的工作,这样您就不必做了。

其他回答

关键在于操作系统是否可能公开API以及如何使用该API的详细描述。

操作系统提供了一组具有调用约定的api。 调用约定定义了将参数提供给API的方式、返回结果的方式以及如何执行实际调用。

操作系统和为它们创建代码的编译器可以很好地协同工作,所以您通常不必考虑它,只需使用它。

创建窗口不需要特殊的语法。所需要的只是操作系统提供一个API来创建窗口。这样的API由c++提供语法的简单函数调用组成。

此外,C和c++是所谓的系统编程语言,能够访问任意指针(可能由硬件映射到某些设备)。此外,调用在程序集中定义的函数也相当简单,这允许处理器提供的全部操作。因此,使用C或c++和少量的汇编程序来编写操作系统本身是可能的。

还应该提到Qt是一个不好的例子,因为它使用所谓的元编译器来扩展c++的语法。然而,这与它调用操作系统提供的api来实际绘制或创建窗口的能力无关。

计算机就像一个洋葱,它有很多很多层,从纯硬件的内核到最外层的应用层。每一层都将自己的一部分暴露给下一个外层,这样外层就可以使用内层的一些功能。

以Windows为例,操作系统为运行在Windows上的应用程序公开了所谓的WIN32 API。Qt库使用该API为使用Qt的应用程序提供自己的API。你使用Qt, Qt使用WIN32, WIN32使用较低级别的Windows操作系统,等等,直到它成为硬件中的电信号。

语言(如c++ 11)是纸上的规范,通常用英语编写。看看最新的c++ 11草案(或者从ISO供应商那里购买昂贵的最终规范)。

你通常使用带有语言实现的计算机(原则上你可以在没有任何计算机的情况下运行c++程序,例如使用一群人类奴隶来解释它;那样既不道德又低效)

你的c++实现通常工作在某个操作系统之上,并与它通信(使用一些特定于实现的代码,通常在一些系统库中)。通常这种通信是通过系统调用完成的。在instance into syscalls(2)中查找Linux内核上可用的系统调用列表。

从应用程序的角度来看,系统调用是一个基本的机器指令,就像x86-64上的SYSENTER一样,具有一些约定(ABI)。

在我的Linux桌面上,Qt库位于X11客户端库之上,通过X Windows协议与X11服务器Xorg通信。

在Linux上,在可执行文件上使用ldd来查看对库的依赖项的(长)列表。在正在运行的进程上使用pmap查看在运行时“加载”了哪些文件。顺便说一句,在Linux上,你的应用程序可能只使用免费软件,你可以研究它的源代码(从Qt,到Xlib, libc,…内核)以了解更多正在发生的事情

你是对的,一般来说,图书馆不能使任何不可能的事情成为可能。

但是库并不一定要用c++来编写才能被c++程序使用。即使它们是用c++编写的,它们也可能在内部使用其他不是用c++编写的库。因此,c++没有提供任何方法来做这件事的事实并不妨碍它被添加,只要在c++之外有某种方法来做这件事。

在相当低的级别上,c++(或C)调用的一些函数将用汇编编写,并且该汇编包含所需的指令,以完成在c++中不可能(或不容易)的操作,例如调用一个系统函数。此时,该系统调用可以做计算机能够做的任何事情,因为没有任何东西可以阻止它。