为什么我们需要在Windows C ++中链接kernel32.dll,user32.dll等?

the*_*ian 2 c++ windows dll linker visual-studio

为什么默认情况下,Visual Studio为什么包含kernel32.dll,user32,dll,winspool.lib等的其他依赖关系?

为什么这些资源需要链接到Windows上的C ++项目中,而实际上却变成了机器代码并直接插入每个可执行文件中,还是与可执行文件分开并在运行时在它们之间建立了链接?

Mik*_*kis 6

为了使C ++应用程序在Windows下运行,它至少需要一些系统服务。例如,它需要分配和释放内存,它需要获取使用它调用的命令行参数,并且它需要能够在完成后退出到操作系统。通常,它还需要以某种方式接收输入并产生输出,无论是通过GUI还是通过控制台,还是通过网络,或者仅仅是通过在文件系统上读写文件。

魔术没有提供这些服务;其中的每一个都由kernel32.dll,user32.dll等提供。

常见的误解是,此功能由C和C ++的标准库提供。事实并非如此,因为如果是的话,那么这些库将能够执行魔术。标准库提供的服务是通过委派给主机系统的本机服务来实现的。

因此,当您调用时,例如malloc()Windows的标准C / C ++库将在内部调用GlobalAlloc()(在Kernel32.dll中实现),而MacOS的标准C / C ++库将在内部调用vm_allocate()或类似的东西。了解这一点非常重要:对于每个不同的主机系统,存在一个不同的标准库实现,这些实现利用了该主机系统的本机服务。

标准库的好处在于它们建立了一个众所周知的通用接口,您的C / C ++代码可以期望使用该接口,因此您的C / C ++代码不必确切地知道也不担心。它在哪个主机系统上运行。

在Windows下,您的程序未完全与DLL链接,因为链接是创建可执行文件的过程,而DLL仅在运行时起作用。您的程序与库链接,因此对于每个DLL通常都有一个对应的LIB。例如,对于Kernel32.DLL,存在Kernel32.LIB,因此您的程序将与Kernel32.LIB链接。

这些LIB很小,因为它们不包含实际的代码。程序运行时,Kernel32.LIB的作用是要求存在相应的Kernel32.DLL,它要求操作系统加载Kernel32.DLL(要求将其映射到进程的内存空间的可能性更大, (因为通常将已经加载Kernel32.DLL),然后它将每个单个库调用重定向到DLL的相应入口点。

因此,是的,每个C ++程序都需要使用这些DLL,否,它不会完全链接DLL本身,它仅链接相应的LIB,然后将调用委托给DLL,而LIB很小,所以不要不用担心他们。

请注意,从理论上讲,有可能编写一个完全独立的程序,不需要任何这些DLL,但是这样的程序实际上将无法执行任何操作:加载后,它将被限制为不执行任何操作,而只能执行以下操作:自己进行内省性思考,既无法接收任何输入,也不会产生任何输出。