linux关于静态库与动态库的使用_笔记

来源:互联网 发布:淘宝c店变成企业店铺 编辑:程序博客网 时间:2024/06/05 18:59

参考文章:

Linux编译多个不同目录下的文件以及静态库、动态库的使用

http://blog.csdn.net/luotuo44/article/details/16970841

动态库与静态库优缺点比较

http://blog.csdn.net/sunshinewave/article/details/39155755


当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被copy到最终的可执行文件中。这就会导致最终生成的可执行代码量相对变多,相当于编译器将代码补充完整了,这样运行起来相对就快些。不过会有个缺点: 占用磁盘和内存空间. 静态库会被添加到和它连接的每个程序中, 而且这些程序运行时, 都会被加载到内存中. 无形中又多消耗了更多的内存空间.

       与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中。这样就使可执行文件比较小, 节省磁盘空间,更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用,也同时节约了内存。不过由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些,总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率,没有好与坏的区别,只看具体需要了。



文件布局如下:


1、编译静态库

在function目录下,执行命令 $g++ -c sub.cpp add.cpp 生成sub.o和add.o文件,然后打包生成静态库,即.a文件

$ar -cr libhead.a add.o sub.o-c :  代表create,创建.a文件-r :  代表replace
注意:

1) 命令中,.a文件要放在.o文件的前面

2) .a文件的格式: 以lib为前缀,.a为后缀,例如 libhead.a

可以使用 $ar -t libhead.a 查看libhead.a文件中包含哪些目标文件,执行结果为 add.o  sub.o


main.c的内容如下:

#include  <iostream>#include  <head.h>using namespace std;int main(int argc, char *argv[]){cout<<add(3, 5)<<endl;cout<<sub(10, 6)<<endl;return 0;}
输入命令生成可执行文件:

$g++ main.cpp -Ifunction -Lfunction -lhead -o main

-I( 大写i ) 告诉编译器在哪里搜索头文件

-L 表示要使用的静态库目录

-l( 小写L ) 表示链接要用的静态库,注意是-lhead,而不是-llibhead,编译器会自动在库中添加lib前缀和.a后缀

注意:要把-l 放在命令尽量靠后的位置,必须放在源文件后面


2、动态库

$g++ -c -fPIC add.cpp sub.cpp 生成位置无关的目标文件

$g++ -shared -fPIC add.o sub.o -o libhead.so 生成.so动态库

$g++ -Ifunction -Lfunction -lhead main.cpp -o main 利用动态库生成可执行文件

但是执行./main却得到如下错误:

libhead.so: cannot open shared object file:

No such file or directory

说明没有找到libhead.so动态库,是因为,linux查找动态库的地方依次如下:

1)  环境变量LD_LIBRARY_PATH 指定的路径

2) 缓存文件 /etc/ld.so.cache 指定的路径

3) 默认的共享库目录,lib 和 /usr/lib

把.so文件放在以上地方即可

或者,可以在生成执行文件的时候指定链接动态库的位置(注意不再使用-L和-l)

$g++ -Ifunction ./libhead.so main.cpp -o main

或者,使用选项-Wl,-rpath,XXXX.其中XXXX表示路径。



原创粉丝点击