前言
Linux下编译动态链接文件会生成.so文件,而编译可执行文件时也要带上此.so文件一起;Windows下编译动态链接文件会生成.dll和.lib文件,编译可执行文件时需要带上.lib文件一起。本文主要介绍为什么可执行文件编译时需要带上.so/.lib文件,以及在这个角度下PE与ELF的一些区别。
本文以调用动态链接库中函数为例来说明。
为什么需要.so/.lib文件
举个例子,对于如下的两个文件:
Lib.c独自编译为动态链接库,Main.c编译为可执行文件,其中main()函数调用了Lib.c中的foo()。注意我们说main()调用了foo(),只是我们期望的结果,那程序怎么去寻找呢?显然我们独自编译Main.c是不可能找到foo()的,整个编译过程都没有Lib.c的存在,上哪找?事实上编译器也不会让Main.c编译通过。
所以编译时至少需要两个信息:函数定义在哪:在动态链接库中还是未定义;
动态链接库文件名是什么:可执行文件运行时可以加载对应的动态链接库。
正是因为需要这些信息,在编译生成使用到动态链接库的可执行文件的时候,才需要.so/.lib文件的参与:用来提供这些信息。下面我们来仔细看看编译时的一些细节问题,.so文件和.lib文件分别对应Linux下的ELF格式和Windows下的PE格式,我们分开讨论。
ELF
示例
Program.c:
Lib.c:
将Lib.c编译为共享对象,生成Lib.so:
编译Program.c,生成Program