当前位置: 首页 > news >正文

计算机基础(六):静态链接与动态链接

上一篇文章简单概括了 C语言程序经过编译,生成汇编语言、机器语言的基本过程。今天主要介绍其中链接阶段的实现思路。

静态链接

静态链接是将被依赖的代码片段复制到执行程序中,进行代码整合。因为我们在汇编代码中看到的是具体的符号,而且每个代码片段都有自己的地址信息,在整合静态代码库的时候,就需要进行对应的符号解析与重定位。

#include <stdio.h>

int main()
{
    printf("Hello, World! \n");
    int res = add(1, 1);
    printf("add result is: %d \n", res);
    return 0;
}

这里调用的add函数是在另一个代码文件 utils.c 中定义的,如果我们直接编译demo.c 则直接报告一个异常:

/tmp/cc3CdEzz.o: In function `main':
demo.c:(.text+0x1e): undefined reference to `add'
collect2: error: ld returned 1 exit statu

此时我们定义另一个文件 utils.c:

#include <stdio.h>

int add(int a, int b)
{
    return a + b;
}

执行编译:

gcc demo.c utils.c

那么将两段代码进行整合时,会将 utils.c 编译后的代码复制到输出文件中,这样执行时自然就能找到依赖的add函数了。

静态链接理解起来并不复杂,其优点是:1. 整个程序里包含了所有的代码,移植到其他机器上不需要安装别的库;2. 由于不需要动态解析,所以执行很快。缺点则更加明显:1. 空间冗余,所有代码在内存中发生冗余;2. 一旦静态链接库发生变化,那么需要将所有依赖静态链接库的代码重新编译一遍。也因此,出现了动态链接来解决这个问题。

动态链接

动态链接库可以被多个运行的程序进行共享,代码不需要每个依赖的程序都拷贝一遍。这样就需要将动态链接库映射到每个运行的程序中才会被执行,又因为映射到每个程序中的地址是不同的,因此需要对动态链接库进行单独的识别与解析。基本原理如下所示:
动态链接示意图

基本使用

gcc -shared -o libutils.so utils.c #生成动态链接库 libutils.so
gcc demo.c libutils.so  #编译

此时如果执行 a.out 的话会出错:

./a.out: error while loading shared libraries: libutils.so: cannot open shared object file: No such file or directory

需要将当前路径导出到动态链接库的访问列表中:

export LD_LIBRARY_PATH=.$LD_LIBRARY_PATH

此时再执行a.out的时候才会成功。

基本原理

程序A和B中都依赖了同一个动态链接库中的某全局数据或函数,因此两者访问库中的数据或函数时,需要加载到自己的程序中执行。但因为地址不一样,需将地址进行映射到对应自己的程序中才能访问。那到底是如何实现映射的呢,这就涉及到ELF中相关的规范了。

ELF

ELF全称是:Executable and Linkable Format

我们的代码被编译、汇编为二进制文件,必须遵循着特定的结构,其中最常见的一种就是 Executable and Linkable Format 的格式。 它广泛用于可执行文件、可重定位目标文件、共享库中。

未完待续……

相关文章:

  • 野花视频免费观看高清在线/安徽seo人员
  • 网站建设后台有哪些项目/大数据营销推广精准粉
  • 网站备案与服务器/吉林seo关键词
  • 有免费建站的网站/7月新闻大事件30条
  • 珠海市人民政府门户网站/南京百度快照优化排名
  • 做设计找素材的 网站有哪些/东莞搜索优化十年乐云seo
  • Tslib配置文件ts.conf
  • 2023年1月16日--2023年1月22日(osg+glsl+socket+ue)
  • 人类从未如此需要知识 知识从未如此昂贵
  • SpringCache之@CachePut注解的使用说明
  • 2022年,开源社最亮的星
  • 来看看我在CSDN上的好朋友们吧,看看有没有你
  • TreeMap 原理实现及常用方法
  • golang实现大顶堆只看这篇文章就够了
  • LeetCode 79 单词搜索 | 解题思路分享
  • 波段之王指标源码
  • 2023/1/15 JS-闭包问题研究
  • 4、字符串处理