动态库、静态库

什么是函数库:

  库文件是函数的具体实现,库文件是通过目标文件(.o)制作成的,所以库文件是多个目标文件的集合。

  生成可执行程序分为四个阶段:预处理、编译(.s)、汇编(.o)、链接

  库文件就用于链接阶段。

  如果一个项目有多个源程序,会将这些源程序经过编译器生成对应的目标文件(这时就有多个源文件对应的目标文件,即多个.o文件),如果源程序又用到其他人实现的函数,

  且这些函数通过库文件(.o文件的集合)提供,最后会将这些.o文件通过链接器生成可执行文件。

静态函数库:

  在链接时,链接器会从库文件中提取所需的代码,拷贝到生成的可执行文件中,这样调用一次就要拷贝一次。

  优点:因为在连接时已经在可执行文件中包含了要用的代码,所以无需依赖静态库就可执行(移植性强)  

  缺点:如果程序中多次调用库文件的同一模块,则会拷贝多次该模块的代码,生成的可执行文件就会包含多段完全相同的代码,将造成代码冗余。

动态库:

  在链接时,哭文件的内容不会进入到可执行文件中,而是将要调用函数的位置信息记录到文件中,然后生成可执行文件,这样可执行文件就要依赖动态库了

  优点:可执行文件记录的是要调用函数的地址,真正的实现代码会在程序运行时被载入内存,所以即便是调用了多次同一的模块,使用的都是同一实现代码

  缺点:可执行文件不能独立执行,必须依赖对应的动态库(可移植性差)

库文件和头文件的联系:

  编译和汇编目的是将一个个源程序汇编成对应的目标程序(即.o程序,这里还不会去调用函数),所以在一个源文件中调用另一个源文件的函数时,如果没有包含那个源文件的头文件,将会有警告:warning: implicit declaration of function ‘xxxx’。所以头文件的作用就体现出来了,就是申明这个函数,告诉这个源程序xxxx函数一定存在,放心使用。

  在链接时会明确要使用的库文件和源文件对应的目标文件,这样才能找到具体的函数实现。如果在链接的时候没有指定要用的库文件,将会报错:

  undefined reference to 'xxx'

  /usr/bin/ld:cannot find -lxxx

  xxx.h:No such file or directory

  https://blog.csdn.net/high_high/article/details/7193264

  http://blog.chinaunix.net/uid-27575921-id-4078661.html

  这里就可以引入makefile的使用了。

 

静态库的制作:

  1. gcc cal.c -o cal.o 生成.o文件

  2. ar rcs libcalfun.a cal.o 用生成的.o文件生成libcal.a静态库。libcalfun.a就是静态库,库名为calfun

静态库的使用:

  gcc main.c -I ../myliclude  -lcalfun -L ./ -o main    // -I是指定头文件所在的路径,“”是在当前目录下找,没找到就从/usr/include或/usr/local/include下找,

                      这样都不会找到,因为头文件再上层路径下的myinclude中,所以手动告诉gcc头文件的搜索路径,加-I选项

                      -l是指定要用的静态库,后面跟库名

                         -L是告诉链接器从指定的路径下找静态库。默认是从/usr/lib或/usr/local/lib下找

  可直接运行可执行文件:./main

 

动态库的制作:

  gcc -share -fpic cal.c -o libcalfun.so  生成libcalfun.so动态库

动态库的使用:

  gcc main.c -lcalfun -L ./ -o main 生成可执行文件,但是直接执行./main会报错

  解决此错误:

  使用命令:export  LD_LIBRARY_PATH="动态库所在的路径" //指定main程序在运行时,到LD_LIBRARY_PATH所指定的路径下去找库文件。

  这样有个弊端,就是只有运行了这条命令的终端才可以执行可执行程序,如果在新的终端中执行该程序,程序还是会报错。

  所以可以在一个脚本文件(main.sh)中写:

  export  LD_LIBRARY_PATH="动态库所在的路径"

  ./main

  再给这个脚本一个可执行权限,这样就可以执行这个脚本了

posted @ 2023-04-10 23:22  踏浪而来的人  阅读(39)  评论(0编辑  收藏  举报