|
一、库文件的简介
库文件也是一种压缩包文件,该文件内部通常包含不止一个目标文件(也就是二进制文件),而每个目标文件存贮的代码,并非完整的程序。而是一个个有具体实用的功能模块。
如C语言库提供的大量数学函数,以及输入输出函数(scanf(), printf(), strlen()等)等,C++库文件不仅提供函数,还有C++语法之外的类,比如String字符串类等等。
库文件可以极大提高编程效率,等于程序的很大一部分组成基材已经由其他人编好了,你只需要拿来直接使用即可。
库文件的调用方法也很简单,例如#include <stdio.h> 之后即可使用 printf()函数。
注意上面的事实说明一个基本模式,所有的C语言库文件都提供相应的头文件。头文件可以认为是库文件调用接口的列表(或说明)。当你自己生成库文件时,库文件由于已经编译,对于用户是保密的,只有头文件提供接口信息,其结果可以在不公开源码的前提下提供功能。
二、静态链接库和动态链接库的简介
C或C++程序从源文件到生成可执行文件需要经历4个阶段,分别为预处理、编译、汇编和链接。
链接阶段要完成的工作,简单来说是将同一项目中各个源文件生成的目标文件和程序中提及的库文件组合,整合成为一个(?)可执行文件。
虽然库文件就是在链接阶段存在的,但编译器并不简单使用一种方式来组合它,而是提供了两种:静态链接和动态链接。
每种链接需要对应不同的库(文件):静态链接库和动态链接库。
在Linux中,静态链接库文件后缀通常为.a, 动态链接库后缀通常为.so 。(在Windows中为.lib 和 .dll)
GCC编译器生成可执行文件时,默认情况下会优先使用动态链接库链接,除非找不到相应动态库,才会选择静态链接库,若还找不到,则链接失败。
Linux发行版库文件一般在/lib 或 /usr/lib 下,但其实可以放在任意位置,见之后所述。
三、静态链接库
GCC进行静态链接的方式很简单,就是在哪里用到库文件的功能,就将该功能模块代码(注意不是库源代码)直接复制到程序文件适当位置,然后生成可执行文件。
静态链接的优势是可移植性强,可独立运行(即执行时不需要静态库文件的存在),缺点是代码冗余,执行文件体积庞大。
如果程序文件多次调用库中的同一功能模块,该模块代码(非源代码)会复制多次。执行文件中代码(非源代码)就会多次重复,所以与动态链接库相比可执行文件有不必要的冗余。
如前所述,静态链接库通常由多个目标文件(.o)组合成一个静态库文件(.a), 具体例程和生成方法如下:
- // so_test.h
- #include <stdio.h>
- void test_a();
- void test_b();
- void test_c();
复制代码- //test_a.c
- #include "so_test.h"
- void test_a()
- {
- printf("This is in test a ... \n");
- }
复制代码- //test_b.c
- #include "so_test.h"
- void test_b()
- {
- printf("This is in test b ... \n");
- }
复制代码- //test_c.c
- #include "so_test.h"
- void test_c()
- {
- printf("This is in test c ... \n");
- }
复制代码 然后编译成目标文件:
- $ gcc -c test_a.c test_b.c test_c.c
复制代码 创建库文件:
- $ ar -r libtest.a test_a.o test_b.o test_c.o
复制代码 调用库文件:
- //main.c
- #include "so_test.h"
- int main()
- {
- test_a();
- test_b();
- test_c();
- return 0;
- }
复制代码 链接:
- gcc main.c libtest.a -o main
复制代码 之后执行看看打印效果:
- $ ./main
- This is in test a ...
- This is in test b ...
- This is in test c ...
复制代码 OK. 以上就是使用静态库的一个小例子,对于使用动态库,请见“有关Linux下C的动态链接库”。Have fun.
|
|