浅尝辄止3-Linux基础-加载库

当我们用C/C++做Linux开发时,肯定会遇到加载库的问题,具体加载的方法要根据具体情况决定。

库文件形式

常见的C/C++库文件有2中形式,即*.a和*.so文件,前者是静态链接库,后者是动态链接库。

静态链接库

静态链接库的文件名一般为*.a,这个a就是archive,即存档的意思。这个文件的内容实际上是*.o的打包。

动态链接库

动态链接库的文件名一般为*.so,相当于windows环境里的*.dll文件。so就是shared object,有共享的意思。这个文件的内容里有很多符号信息,是动态链接过程中的必要信息。

两种库的特点

首先说静态,动态是指什么。他们的宾语都是链接,所以这两种库的链接情况不同。所谓链接,就是你的代码在引用一个符号的时候,链接器找到那个符号的动作。
静态链接就是找符号的动作在编译阶段就完成了。为什么能这么早搞定呢?因为静态链接的结果是把整个库的内容都放到目标文件里了,所有符号的完整信息都在自己手里了,找符号还不容易么?
动态链接就是找符号的动作要在运行时完成,目标文件里肯定没有符号的完整信息,所以要快用的时候才现找。那么问题又来了,自己没带着的东西,用的时候去哪找呢?当然是在目标运行环境上找啦。只要目标运行环境里有对应的库,并且在加载器的搜索路径下,就可以找到的。
总的来说,使用动态链接库的程序,目标文件小,省磁盘空间,当然,前提是目标运行环境有这个库,如果拿不准,那就只能用静态链接库。

库的生成

静态链接库生成要用ar命令一般形式是
ar -r lib.a .o

例如对于代码文件test.c,如下命令可以得到libtest.a

gcc -c -o test.o test.c
ar -r libtest.a test.o
动态链接库直接用gcc就可以生成,一般形式为
gcc -c -fPIC *.c -o *.o
gcc -shared -o lib*.so *.o

例如对于代码文件test.c,如下命令可以得到libtest.so

gcc -c -fPIC -o test.o test.c
gcc -shared -o libtest.so test.o

库的使用

两种库的使用有一种共通的编译方法

gcc *.c -L -L -l -l -o a.out

-L是要指定库的搜索路径,编译环境中的LIBRARY_PATH已经包含的路径就不用指定了。
-l是要指定库的名字,例如库文件是libtest.so或libtest.a,那就要写成-ltest
那么问题来了,如果两种链接库同时存在,编译器会用怎样的链接方式呢?答案是动态链接,如果要优先使用静态链接,要用-static

dl*系列函数

上面的编译方法,要求必须有库存在编译环境中。其中,静态库的内容必须是正确的代码,动态库的内容的符号必须是正确的,函数内部的实现方法可以不正确,因为在运行环境中会调用正确的库。
当编译环境中没有需要的动态库文件怎么办呢?动态加载库还有一种使用方法,在代码逻辑中加载,可以使用库函数DLOPEN(3)以及相关函数,相关例子代码网上不少,我就懒得写了。

你可能感兴趣的:(浅尝辄止3-Linux基础-加载库)