头文件与库文件
1、概要
在使用C语言和其它语言进行程序设计的时候,我们须要头文件来提供对常数的定义和对系统及库函数调用的声明。
库文件是一些预先编译好的函数集合,那些函数都是依照可重用原则编写的。它们通常由一组互相关联的用来完毕某项常见工作的函数构成。比方用来处理屏幕显示情况的函数(ncurses库)和数据库訪问例程(dbm库)等。
2、使用库的长处:
1)模块化开发
2)可重用性
3)可维护性
3、头文件与库文件的位置
/usr/include及其子文件夹底下的include文件夹
/usr/local/include及其子文件夹底下的include文件夹
/usr/lib
/usr/local/lib
/lib
4、使用外部库【-i选项】
//例程 #include <math.h> #include <stdio.h> int main() { double ans = pow(2.0,3.0); printf("pow(%lf,%lf) = %lf\n",2.0,3.0,ans); return 0; }
编译:
gcc -Wall calc.c -o calc -lm
#-lm表示要链接libm.so或者libm.a库文件
静态库与共享库
1、概要
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件里。程序执行的时候将不再须要静态库。静态库占用磁盘空间较大。
共享库(.so/.sa):程序在执行的时候才去链接共享库的代码。多个程序可共享使用库的代码。[近期的Linux[CentOS 6.4]版本号在/usr以及/lib文件夹下已经找不到.a文件的踪影了]
2、共享库的长处:
一个与共享库链接的可执行文件只包括它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件開始执行曾经,外部函数的机器码由操作系统从磁盘上的该共享库中拷贝到内存中,这个过程称为动态链接(dynamic linking)
共享库能够在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。
操作系统採用虚拟内存机制同意物理内存中的一份共享库被要用到该库的全部进程共用,节省了内存和磁盘空间。
生成静态库
-能够简单的觉得将多个.o文件打包到一起,就生成了静态库
1)gcc -c hello_fn.c
#同gcc -Wall -c hello_fn.c -o hello_fn.o
2)ar rcs libhello.a hello_fn.o search.o
#arar是gnu归档工具。rcs表示(replace and create),相当于将将.o文件打包成为.a文件,而且.o文件能够有多个
3)gcc -Wall main.c libhello.a -o main
#将各个模块编译,链接生成可执行文件【方式一】
4)gcc -Wall -L. main.c -o main -lhello
#-L.表示在当前文件夹搜索库文件,-lhello[省略的lib],此时即使删除静态库libhello.a也可执行main文件【方式二】
库的搜索路径
1)从左到右搜索-I -L指定的文件夹。
2)由环境变量指定的文件夹
能够定义C_INCLUDE_PATH/CPP_INCLUDE_PATH(头文件搜索路径)、LIBRARY_PATH(库文件搜索路径)保存在~/.bash_profile中,另在Ubuntu系统中,也能够将这些定义存放在~/.bashrc中
3)由系统指定的文件夹:/usr/include,/usr/lib等
生成共享库
gcc -shared -fPIC hello_fn.o -o hello_fn.so
说明:
1)shared表示生成共享库
2)-fPIC表示生成位置无关码(Position Independent Code)
3)库的命名规则:libXXX.so[.版本号号]
使用共享库
1)gcc main.o -o main –L. -lhello
#该命令与使用静态库的命令同样,可是,在共享库与静态库共存的情况下,优先使用共享库
l:链接共享库,只要库名就可以(去掉lib以及版本号号)
L:链接库所在的路径.
2)执行共享库
法1)拷贝.so文件到系统共享库路径下,一般指/usr/lib
法2)在~/.bash_profile文件里,配置LD_LIBRARY_PATH变量
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
. ~/.bash_profile
法3)配置/etc/ld.so.conf。配置完毕后调用ldconfig更新ld.so.cache
3)ldd命令:用于查看程序执行时须要载入的共享库