linux下的静态链接和动态链接(一)

    静态链接:静态链接就是,在生成可执行程序的时候,把目标文件.o 和 静态库 .a ,使用 ld 链接器,链接生成一个可执行程序。这是在程序加载前就完成的动作。

    动态链接:动态链接就是,在生成可执行程序的时候,只是引用的未定义的符号作了标识,到加载到内存中的时候才进行符号重定位。

静态库的生成:

  以 Lib.c为例子,代码如下:

#include 

void foobar(int i)
{
   printf("jing tai ku shengcehng!");
}

使用 gcc -c Lib.c 命令生成 Lib.o 文件。

再用 ar cr LIb.a Lib.o 来生成一个静态库。

动态库的生成:

也是以 Lib.c 为例子,代码如下:

#include 

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 查看它的符号情况,如图:

linux下的静态链接和动态链接(一)_第1张图片

    可以看到 foobar 的符号类型是 U (未定义),说明引用的是 Lib.so 动态库里的符号。

    第二次,我使用 gcc -o program program.c ./Lib.a ./Lib.so 来生成可执行文件 program, 再次使用 nm program 来查看里面符号的情况,如图:

linux下的静态链接和动态链接(一)_第2张图片

    从图中可以看到 foobar 符号的类型为 T(说明在 .text 段里),这说明引用的是静态库里的 foobar 符号。

得出结论:

    当编译的时候使用的静态库和动态库里都有某个符号的定义,那么哪个在前面就引用哪个的符号定义。(其实可以执行运行程序就可以得到答案了)。

你可能感兴趣的:(c/c++)