首页 存档 技术 查看内容

Linux下的静态库、动态库和动态加载库

2018-3-30 13:00 |来自: 互联网 398 0

摘要: 点击上方“蓝字”可以关注我们哦 |转载自:www.pchou.info |原文链接:http://www.pchou.info/linux/2016/07/17/linux-libraries.html 库的存在极大的提高了C/C 程序的复用性,但是库对于初学者来说有些难以驾驭, ...

点击上方“蓝字”可以关注我们哦



|转载自:www.pchou.info

|原文链接:http://www.pchou.info/linux/2016/07/17/linux-libraries.html



库的存在极大的提高了C/C 程序的复用性,但是库对于初学者来说有些难以驾驭,本文从Linux的角度浅谈Linux下的静态库、动态库和动态加载库。


Linux库类型


Linux下可以创建两种类型的库:


静态库(.a): 在链接期间被应用程序直接链接进可执行文件


动态链接库(.so): 动态库还分为两种用法: a) 应用程序运行期间链接动态库,但是在编译期间声明动态库的存在,也就是说这种动态库必须在编译时对编译器可见,但编译器却不将此种库编译进可执行文件; b) 在运行期间,动态加载和卸载的库,使用动态加载方法加载。这种库的形式跟动态链接没有本质区别,区别是在调用时,是由用户程序决定何时链接的,而不是由系统链接器自动链接


命名约定


库需要以lib作为开头,而在指定链接命令行参数时,却无需包含开头和扩展名,例如:


gcc src-file.c -lm -lpthread

这个例子中,链接了libmath.a和libpthread.a


静态库(.a)


生成静态库的方法如下:


编译object文件。例如:cc -Wall -c ctest1.c ctest2.c,该命令会生成ctest1.o和ctest2.o(其中-Wall表示编译时输出警告)。


创建库文件。例如:ar -cvq libctest.a ctest1.o ctest2.o。该命令会得到一个libctest.a文件


可以通过ar -t查看.a文件中包含哪些.o。所以,实际上ar就是一个打包命令,类似tar


构建符号表。ranlib libctest.a用于为.a创建符号表。有些ar命令实际上已经集成了ranlib的功能


.a文件与windows下的.lib是相同的概念。


动态库(.so)


生成动态库的方法如下:


编译object文件时使用-fPIC选项:


gcc -Wall -fPIC -c *.c

这个选项的目的是让编译器生成地址无关(position independent)的代码,这是因为,动态库是在运行期间链接的,变量和函数的偏移量是事先不知道的,需要链接以后根据offset进行地址重定向。


使用-shared链接


gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o

-shared选项是让动态库得以在运行期间被动态链接;-Wl,options是设置传递给ld(链接器)的参数,在上面的例子中,当链接器在链接.o时会执行ld -soname ibctest.so.1


创建软链


上面的命令将最终输出一个动态库libctest.so.1.0,而出于习惯,会创建两个软链:


mv libctest.so.1.0 /opt/lib

ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1

ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so

libctest.so用于在编译期间使用-lctest让编译器找到动态库,而libctest.so.1用于在运行期间链接


gcc -Wall -I/path/to/include-files -L/path/to/libraries prog.c -lctest -o prog

查看依赖


使用ldd命令来查看程序对动态库的依赖。例如:

ldd prog

libctest.so.1 =

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部