动态库和静态库
前提:本文是基于Linux系统下的编程与学习
补充:头文件卫士,避免头文件重复包含。
//头文件卫士 #ifndef __HEAD_H__ #define __HEAD_H__ //头文件内容 #endif //__HEAD_H__
命令:nm
nm 二进制文件名; 可以查看二进制文件的符号表
那么符号表里都有哪些内容呢?
全局变量的名字, 静态局部变量的名字, 函数的名字
静态库和动态库
//main.c #include <stdio.h> #include "t_math.h" int main(){ printf("3+5=%d\n", add(3,5)); printf("5-3=%d\n", mul(5,3)); return 0; }
1 //t_math.c 2 5 int add(int a,int b){ 6 return a+b; 7 } 8 9 int mul(int a,int b){ 10 return a-b; 11 }
1 //t_math.h 2 #ifndef __T_MATH_H__ 3 #define __T_MATH_H__ 4 5 int add(int a,int b); 6 int mul(int a,int b); 7 8 #endif //__T_MATH_H__
生成静态库:
a. 将要加入静态库的源文件编译成目标文件 gcc -c t_math.c
b. 将目标文件打包到静态库文件中 ar -r -o libtmath.a t_math.o
c. 使用静态库文件链接生成可执行文件
gcc -c main.c
gcc main.o -L. -ltmath
补充:-L路径:链接器搜索库文件的路径; -l库名:告诉链接器找那个库
使用静态库生成的可执行文件,链接发生在生成可执行文件之前;称为静态链接。可执行文件不依赖于静态库文件。
生成动态库(又称共享库):
a. 将要加入动态库的源文件编译成与位置无关的目标文件 gcc -c -fPIC t_math.c
b. 将第一步生成的目标文件打包到动态库文件 gcc -shared -o libtmath.so t_math.o
c. 使用动态库文件链接生成可执行文件
gcc -c main.c
gcc main.o -L. -ltmath
在生成可执行文件的时候,发生了链接,但是这个链接是一个虚的链接,真是的链接发生在代码加载到内存的时候。这个真是的链接是动态链接。
使用动态链接库生成的可执行文件,是动态链接。这个可执行文件依赖于动态库文件。
如何查看一个可执行程序依赖于哪些动态库文件呢? ldd
day03$ldd a.out
linux-gate.so.1 => (0xb76f5000)
libtmath.so => not found
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb751e000)
/lib/ld-linux.so.2 (0xb76f6000)
加载器 错误的原因就是加载器找不到动态库。
解决这个问题,就需要告诉加载器到哪里去找动态库文件
两种方法:
1、加载器的默认路径
/usr/lib或者 /lib
链接器的默认路径也是它。
2、使用环境变量告诉加载器到哪里去找。
LD_LIBRARY_PATH 加载器使用的环境变量。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
动态链接和静态链接的区别
执行文件的时候。 发生实际的链接。完全依赖动态库
生成可执行文件的时候,发生实际的链接 不再依赖静态库