当我制作 C++ 应用程序时,我通常使用SDL或WxWidgets等库。但是如果我要制作图书馆,我是否需要使用图书馆来制作图书馆?或者我可以用核心 C++ 代码制作整个库,这甚至可能吗?
我的观点是,必须有一点是库没有任何基础,所以它唯一可以使用的是核心 C++。
我对这个理论正确吗?如果不是,那么低级库是如何真正制作的?
(我知道这是一个广泛的问题,但我是一个非常好奇的人,需要答案,这让我很困扰。)
低级库通过操作系统提供的库来访问硬件和系统资源。操作系统本身及其加载的驱动程序使用预定义内存地址的汇编和读/写来修改 CPU 状态并与硬件通信。
仅依赖于C++的库只能是实用程序库,因为与硬件或用户的任何通信都将涉及程序集或附加库。一个没有依赖关系的纯 C++ 库的示例是数学库,因为它不需要 I/O 或硬件访问。
当我制作 C++ 应用程序时,我通常使用 SDL 或 wxWidgets 等库。但是如果我要制作图书馆,我是否需要使用图书馆来制作图书馆?或者我可以用核心 C++ 代码制作整个库,这甚至可能吗?
是的。
我的观点是必须有一点,一个库没有任何基础,所以它唯一可以使用的东西是核心 C++。
不。
C & C++ 是第三代语言的例子。因此,他们试图隐藏许多系统方面的实现细节。第三代编程语言(3GL) 层的基础是第二代编程语言(2GL),例如x86 汇编;下面我们有机器代码指令。
正如 josefx 已经指出的那样,您确实可以在纯 C++ 中实现 C++ 库。然而,系统库(尤其是那些用于控制设备的库)可以并且经常是用汇编程序编写的。通常,库也可以用COBOL或Fortran甚至Brainfuck编写。
汇编器/编译器/链接器进程实际上将2GL/3GL
代码转换为library
可以在 C++ 中链接到的代码。
这是一个 C 程序的小例子,它没有blah.c
链接到标准运行时库,但它仍然设法使用 * 专有库中的函数打印出东西, 写在:libfoo.a,
x86 assembler
/*-----------------------------------------------
blah.c
Invokes some assembly
------------------------------------------------*/
void _start()
{
char sz[]={"oOoook\n"};
foo(sz,sizeof(sz));
byebye();
}
;----------------------------------------------------------------------------
;Some foo assembly: exposes system write & exit
;----------------------------------------------------------------------------
SECTION .text
global foo
global byebye
foo:
push ebp
mov ebp,esp
mov edx, [ebp+12]
mov ecx, [ebp+8]
mov ebx,1
mov eax,4 ;syscall for __NR_write
int 0x80 ;service interrupt
mov esp,ebp
pop ebp
mov eax,0
ret
byebye:
mov ebx,0
mov eax,1 ;syscall for __NR_exit
int 0x80 ;service interrupt
ret
这是它的构建方式:
$ nasm -felf -ofoo.o foo.asm
$ ar rs libfoo.a foo.o
$ gcc -L. -oblah blah.c -lfoo -nostartfiles -nostdlib -nodefaultlibs
$ ./blah
oOoook
$
可以看出,该库使用系统调用(在本例中为linux
内核);顺便说一句,也可以由第三方实施。
库分为三种:
进行系统调用的库通常不能用语言本身编写,因为它依赖于系统调用约定的特殊性,这通常涉及对内核进行陷阱或中断,以导致切换到较低权限的环. 纯 C++ 中没有生成陷阱/中断的工具;OS API 通常使用程序集扩展来执行此操作。
第二类是制定或接收外部调用约定的库;可以说系统调用是其中的一个子类别,但是系统调用明显不同,因为系统调用需要特权环切换,而外部调用则不需要。外部调用约定通常也用汇编语言编写。
所有其他不涉及 ring switch 或外部调用约定的库总是可以用 C++ 本身编写;尽管有时它们不是,但通常出于性能目的(例如数学库属于此类别)。
在任何情况下,属于前两类的库通常也有大量用纯 C++ 编写的代码,它们什么都不做,只是将系统调用/外部调用的 API 包装成 C++ 工具和程序员更熟悉的形式(例如头文件和其他便利实用程序)。
从本质上讲,库只是类的集合。它们可以基于其他库来扩展它们或完全为新库提供核心。您可以仅使用 C++ 代码创建自己的库,例如,利用 Windows API 的图形库、扩展可用套接字库的聊天/通信库等。您说这些库使用核心 C++ 是正确的功能。
库只不过是您可以链接代码的其他代码。它们没有什么神奇或特别之处。你可以把你写的函数变成一个库。所以问题真的是你能只做低级的东西 C++ 还是你必须做其他事情?好吧,这就是 Lie Ryan 的答案所在。您可以编写程序,做您的事,只需要 C++ 代码。您可以进行系统调用,并且可以绑定其他语言(例如汇编)来完成您在 C++ 中无法完成但需要执行的操作。
最后,这一切都归结为机器代码和硬件。获得该机器代码或功能相同的东西所需或需要的任何语言或方法都在可能性范围内。不必要地使用 asm 或不使用系统调用等可能并不总是最聪明的事情。
有大量的开源库与您正在谈论的那些类似,您只需查看代码即可了解它们是如何做到的。没有什么可以说明一个实体实现某事的方式是唯一的方法。