静态链接:静态链接就是,在生成可执行程序的时候,把目标文件.o 和 静态库 .a ,使用 ld 链接器,链接生成一个可执行程序。这是在程序加载前就完成的动作。
动态链接:动态链接就是,在生成可执行程序的时候,只是引用的未定义的符号作了标识,到加载到内存中的时候才进行符号重定位。
静态库的生成:
以 Lib.c为例子,代码如下:
#include <stdio.h>
void foobar(int i)
{
printf("jing tai ku shengcehng!");
}
使用 gcc -c Lib.c 命令生成 Lib.o 文件。
再用 ar cr LIb.a Lib.o 来生成一个静态库。
动态库的生成:
也是以 Lib.c 为例子,代码如下:
#include <stdio.h>
void foobar(int i)
{
printf("动态库的生成!");
}
使用 gcc -fpic -shared -o Lib.so Lib.c 来生成一个动态库 Lib.so.
当我看《程序员的自我修养》里面的动态连接的介绍的时候,我在想要是静态库和动态库里都有某个函数的定义,编译的时候也同时指定这两个静态库和动态库,那么到底会引用哪个符号呢?
验证的代码如下:Lib.h
#ifndef LIB_H
#define LIB_H
void foobar(int i);
#endif
program.c
#include "Lib.h"
int main()
{
foobar(1);
return 0;
}
第一我使用 gcc -o program program.c ./Lib.so ./Lib.a 来生成可执行程序 program。然后使用 nm program 查看它的符号情况,如图:
可以看到 foobar 的符号类型是 U (未定义),说明引用的是 Lib.so 动态库里的符号。
第二次,我使用 gcc -o program program.c ./Lib.a ./Lib.so 来生成可执行文件 program, 再次使用 nm program 来查看里面符号的情况,如图:
从图中可以看到 foobar 符号的类型为 T(说明在 .text 段里),这说明引用的是静态库里的 foobar 符号。
得出结论:
当编译的时候使用的静态库和动态库里都有某个符号的定义,那么哪个在前面就引用哪个的符号定义。(其实可以执行运行程序就可以得到答案了)。