我正在学习c++,我刚刚开始学习Qt的一些功能来编写GUI程序。我问了自己以下问题:
c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络进行通信的方式(我承认我也不完全理解api),它是如何通过c++本身编写的库突然获得这些功能的?在我看来,这一切都是可怕的循环。你能在这些库中找到哪些c++指令?
我知道这个问题对一个有经验的软件开发人员来说似乎微不足道,但我已经研究了几个小时,没有找到任何直接的回答。这已经到了我无法理解Qt教程的地步,因为库的存在对我来说是不可理解的。
我正在学习c++,我刚刚开始学习Qt的一些功能来编写GUI程序。我问了自己以下问题:
c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络进行通信的方式(我承认我也不完全理解api),它是如何通过c++本身编写的库突然获得这些功能的?在我看来,这一切都是可怕的循环。你能在这些库中找到哪些c++指令?
我知道这个问题对一个有经验的软件开发人员来说似乎微不足道,但我已经研究了几个小时,没有找到任何直接的回答。这已经到了我无法理解Qt教程的地步,因为库的存在对我来说是不可理解的。
当前回答
语言(如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++程序使用Qt库(也是用c++编写的)。Qt库将使用Windows CreateWindowEx函数(在kernel32.dll中用C编写)。或者在Linux下,它可能使用Xlib(也是用C编写的),但它也可以发送原始字节,在X协议中意味着“请为我创建一个窗口”。
与你的两难问题相关的是“第一个c++编译器是用c++编写的”的历史注释,尽管实际上它是一个带有一些c++概念的C编译器,足以编译第一个版本,然后它可以编译自己。
类似地,GCC编译器使用GCC扩展:它首先被编译到一个版本,然后用于重新编译自身。(GCC构建说明)
关键在于操作系统是否可能公开API以及如何使用该API的详细描述。
操作系统提供了一组具有调用约定的api。 调用约定定义了将参数提供给API的方式、返回结果的方式以及如何执行实际调用。
操作系统和为它们创建代码的编译器可以很好地协同工作,所以您通常不必考虑它,只需使用它。
c++是如何…突然通过库获得这些功能 用c++写的?
使用其他库并没有什么神奇的。库是可以调用的简单的大函数包。
假设你在写一个这样的函数
void addExclamation(std::string &str)
{
str.push_back('!');
}
现在如果你包含这个文件,你可以写addex叹号(myVeryOwnString);。现在你可能会问,“c++是怎么突然有能力在字符串中添加感叹号的?”答案很简单:你写一个函数来做这件事,然后你调用它。
因此,要回答你关于c++如何通过c++编写的库获得绘制窗口的能力的问题,答案是相同的。其他人写函数来做这些,然后编译它们,并以库的形式提供给你。
其他问题回答了窗口绘图的实际工作方式,但你听起来对库的工作方式感到困惑,所以我想解决你问题中最基本的部分。
硬件是允许这一切发生的原因。您可以将图形存储器看作一个大数组(由屏幕上的每个像素组成)。要绘制到屏幕上,您可以使用c++或任何允许直接访问该内存的语言写入该内存。该内存恰好可以被显卡访问或位于显卡上。
在现代系统中,由于各种限制,直接访问图形存储器需要编写驱动程序,因此您可以使用间接方法。库创建一个窗口(实际上只是一个像其他图像一样的图像),然后将该图像写入图形内存,然后GPU将其显示在屏幕上。除了写入特定内存位置的能力之外,该语言不需要添加任何东西,这就是指针的作用。
创建窗口不需要特殊的语法。所需要的只是操作系统提供一个API来创建窗口。这样的API由c++提供语法的简单函数调用组成。
此外,C和c++是所谓的系统编程语言,能够访问任意指针(可能由硬件映射到某些设备)。此外,调用在程序集中定义的函数也相当简单,这允许处理器提供的全部操作。因此,使用C或c++和少量的汇编程序来编写操作系统本身是可能的。
还应该提到Qt是一个不好的例子,因为它使用所谓的元编译器来扩展c++的语法。然而,这与它调用操作系统提供的api来实际绘制或创建窗口的能力无关。