Linux下使用的函数库分两种,静态库和动态库, 一般分别以后缀.a和.so来区别,其实就类似于Windows平台下的.lib和.dll.
静态库一般是源代码只进行编译后生成的目标文件,不需要进行链接直接将该目标文件打包成函数库.对这类静态函数库的使用,是在编译链接使用了静态库的源代码文件时,指定好静态库文件(目标文件),将这些静态库(目标文件)一起链接进最终的可执行文件中去.所以在最终执行程序时,静态库中被使用到的函数是随程序启动开始就被加载到内存中去的.这中情况其实和我们在编写包含多个cpp文件的程序时,一起链接这些cpp文件编译生成的多个.o文件(目标文件)是一样的,只不过文件后缀由.o变成了.a.
如果需要在自己的代码中使用这类静态库,则只要在自己的源代码中include进这些静态库所对应的.h文件(头文件)即可,然后在链接的时候(编译的时候有.h文件就够了,还用不到静态库文件)指定好所用到的静态库文件,就会将这些静态库一起链接进来,生成最终的可执行文件.
示例:
首先,分别编写Print_s.h和Pint_s.cpp文件,这是静态库的源代码.
//Print_s.h
include <stdio.h>
#include <iostream>
int Print();
下面是Print.cpp.
//Print_s.cpp
#include "Print_s.h"
int Print()
{
printf("TEST!\n");
return 0;
}
编完之后,编译出静态库来.
g++ -c -o libPrint.a Print.cpp
这个地方一定要指定-c参数,表示只编译不链接成可执行文件,因为没有main函数,所以不能链接生成可执行文件,链接器会报错.
编译生成了一个名为libPrint.a的目标文件,这个就是我们后面要用的静态库文件.
然后,就编写一个使用静态库libPrint.a的程序.
//PrintName_s.h
#include <stdio.h>
#include <iostream>
下面是PrintName_s.cpp.
#include "Print_s.h"
#include "PrintName_s.h"
int main()
{
Print();
printf("Finished execute Print() !\n");
return 0;
}
编完之后,编译PrintName_s.cpp,假设Pirnt_s.h和libPrint.a都放在/opt/temp/下.
g++ -I /opt/temp/ -L /opt/temp/ -lPrint -o PrintName_s.bin PrintName_s.cpp
其中
-L /opt/temp/
是告诉链接器搜索路径(当然是追加)
-lPrint
是给链接器指定库文件名,因为Linux下的库文件名一般都为.a或.so,所以-lPrint其实就是指定名称为libPrint.a或者libPrint.so的库文件名.
或者也可以直接
g++ -I /opt/temp/ /opt/temp/libPrint.a -o PrintName_s.bin PrintName_s.cpp
两种方法生成的PrintName_s.cpp大小是一样的.
执行./PrintName_s.bin后输出
TEST!
Finished execute Print() !
动态库是将一组函数编译链接成的一个共享的库文件.使用时,也是需要在编译链接源代码时,指定动态库文件名称,但与使用静态库文件不同,使用动态库进行链接,在链接生成最终的可执行文件的时候,不会将用到的库中的函数直接链接进可执行文件中来,而只是先链接进来一个函数的符号连接,这样,在执行该可执行程序的时候,程序不会在一开始启动的时候就把那些使用到的动态库中的函数加载进来,而是等到具体执行到使用这些函数的代码时才动态加载进来这些库函数,也就是说到用的时候再加载进来.