Linux 下动态库文件的文件名形如 libxxx.so,其中 so 是 Shared Object 的缩写,即可以共享的目标文件。
在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是在执行文件中记录对动态库的引用。
程序执行时,再去加载动态库文件。如果动态库已经加载,则不必重复加载,从而能节省内存空间。
Linux 下生成和使用动态库的步骤如下:
- 编写源文件。
- 将一个或几个源文件编译链接,生成共享库。
- 通过
-L<path> -lxxx的 gcc 选项链接生成的 libxxx.so。 - 把 libxxx.so 放入链接库的标准路径,或指定
LD_LIBRARY_PATH,才能运行链接了 libxxx.so 的程序。
源文件
样例
//max.c
int max(int n1, int n2, int n3)
{
int max_num = n1;
max_num = max_num < n2? n2: max_num;
max_num = max_num < n3? n3: max_num;
return max_num;
}
共享库
编译生成共享库:
$ gcc -fPIC -shared -o libmax.so max.c
-fPIC是编译选项,PIC 是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性;
-shared是链接选项,告诉 gcc 生成动态库而不是可执行文件。
编写头文件
为了让用户知道我们的动态库中有哪些接口可用,我们需要编写对应的头文件。
//max.h
#ifndef __MAX_H__
#define __MAX_H__
int max(int n1, int n2, int n3);
#endif
测试
编写一个测试程序 test.c 引用编译好的 libmax.so
//test.c
#include <stdio.h>
#include "max.h"
int main(int argc, char *argv[])
{
int a = 10, b = -2, c = 100;
printf("max among 10, -2 and 100 is %d.\n", max(a, b, c));
return 0;
}
编译命令
$ gcc test.c -L. -lmax -o test
-lmax表示要链接libmax.so
-L.表示搜索要链接的库文件时包含当前路径
运行
$ ./test
max among 10, -2 and 100 is 100.
自动化编译
利用 make 来进行自动化编译
.PHONY: build test clean
build: libmax.so
libmax.so: max.o
gcc -o $@ -shared $<
max.o: max.c
gcc -c -fPIC $<
test: test.c libmax.so
gcc test.c -L. -lmax -o test
clean:
rm -f *.o *.so a.out
用法
$ make build # 编译动态库 libmax.so
$ make test # 生成 test 可执行程序
$ make clean # 清理编译和测试结果
附录
例程见我的Github
相关博文 Linux 静态库编译指南。