我正在学习c++,我刚刚开始学习Qt的一些功能来编写GUI程序。我问了自己以下问题:
c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络进行通信的方式(我承认我也不完全理解api),它是如何通过c++本身编写的库突然获得这些功能的?在我看来,这一切都是可怕的循环。你能在这些库中找到哪些c++指令?
我知道这个问题对一个有经验的软件开发人员来说似乎微不足道,但我已经研究了几个小时,没有找到任何直接的回答。这已经到了我无法理解Qt教程的地步,因为库的存在对我来说是不可理解的。
我正在学习c++,我刚刚开始学习Qt的一些功能来编写GUI程序。我问了自己以下问题:
c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络进行通信的方式(我承认我也不完全理解api),它是如何通过c++本身编写的库突然获得这些功能的?在我看来,这一切都是可怕的循环。你能在这些库中找到哪些c++指令?
我知道这个问题对一个有经验的软件开发人员来说似乎微不足道,但我已经研究了几个小时,没有找到任何直接的回答。这已经到了我无法理解Qt教程的地步,因为库的存在对我来说是不可理解的。
当前回答
硬件是允许这一切发生的原因。您可以将图形存储器看作一个大数组(由屏幕上的每个像素组成)。要绘制到屏幕上,您可以使用c++或任何允许直接访问该内存的语言写入该内存。该内存恰好可以被显卡访问或位于显卡上。
在现代系统中,由于各种限制,直接访问图形存储器需要编写驱动程序,因此您可以使用间接方法。库创建一个窗口(实际上只是一个像其他图像一样的图像),然后将该图像写入图形内存,然后GPU将其显示在屏幕上。除了写入特定内存位置的能力之外,该语言不需要添加任何东西,这就是指针的作用。
其他回答
关键在于操作系统是否可能公开API以及如何使用该API的详细描述。
操作系统提供了一组具有调用约定的api。 调用约定定义了将参数提供给API的方式、返回结果的方式以及如何执行实际调用。
操作系统和为它们创建代码的编译器可以很好地协同工作,所以您通常不必考虑它,只需使用它。
When you try to draw something on the screen, your code calls some other piece of code which calls some other code (etc.) until finally there is a "system call", which is a special instruction that the CPU can execute. These instructions can be either written in assembly or can be written in C++ if the compiler supports their "intrinsics" (which are functions that the compiler handles "specially" by converting them into special code that the CPU can understand). Their job is to tell the operating system to do something.
When a system call happens, a function gets called that calls another function (etc.) until finally the display driver is told to draw something on the screen. At that point, the display driver looks at a particular region in physical memory which is actually not memory, but rather an address range that can be written to as if it were memory. Instead, however, writing to that address range causes the graphics hardware to intercept the memory write, and draw something on the screen. Writing to this region of memory is something that could be coded in C++, since on the software side it's just a regular memory access. It's just that the hardware handles it differently. So that's a really basic explanation of how it can work.
我如何看待这个问题,这实际上是一个编译器的问题。
这样看,你用汇编写了一段代码(你可以用任何语言写),它把你新写的语言(你想把z++称为汇编)翻译成汇编,为了简单起见,让我们称它为编译器(它是编译器)。
现在你给了这个编译器一些基本的函数,这样你就可以写int,字符串,数组等等,实际上你给了它足够的能力,所以你可以用z++来写编译器本身。现在你有了一个用z++编写的z++编译器,非常简洁。
更酷的是,现在您可以使用编译器已有的功能为其添加功能,从而通过使用以前的功能扩展z++语言的新功能
举个例子,如果你写了足够多的代码来绘制任何颜色的像素,那么你可以使用z++扩展它来绘制任何你想要的东西。
c++是如何…突然通过库获得这些功能 用c++写的?
使用其他库并没有什么神奇的。库是可以调用的简单的大函数包。
假设你在写一个这样的函数
void addExclamation(std::string &str)
{
str.push_back('!');
}
现在如果你包含这个文件,你可以写addex叹号(myVeryOwnString);。现在你可能会问,“c++是怎么突然有能力在字符串中添加感叹号的?”答案很简单:你写一个函数来做这件事,然后你调用它。
因此,要回答你关于c++如何通过c++编写的库获得绘制窗口的能力的问题,答案是相同的。其他人写函数来做这些,然后编译它们,并以库的形式提供给你。
其他问题回答了窗口绘图的实际工作方式,但你听起来对库的工作方式感到困惑,所以我想解决你问题中最基本的部分。
首先,我觉得有一点误会
c++以前没有语法能够要求操作系统提供一个窗口或一种通过网络通信的方式,它是如何做到的呢
没有用于操作系统操作的语法。这是语义学的问题。
突然通过c++本身编写的库获得这些功能
操作系统主要是用c编写的。您可以使用共享库(即dll)来调用外部代码。此外,操作系统代码可以在系统调用*或中断上注册系统例程,您可以使用程序集调用这些例程。共享库通常只是为您进行系统调用,因此您可以避免使用内联汇编。
这里有一个很好的教程:http://www.win.tue.nl/~aeb/linux/lk/lk-4.html 它适用于Linux,但原理是相同的。
操作系统如何对显卡、网卡等进行操作?这是一个非常广泛的主题,但大多数情况下你需要访问中断,端口或写入一些数据到特殊的内存区域。由于这些操作是受保护的,所以无论如何都需要通过操作系统调用它们。