C动态链接与静态链接

个人很看重编译和链接这层的东西,简单谈一谈C语言的动态链接和静态链接

动态链接

简介

在做程序开发的时候,有许多简单的函数是很常用的,但是如果每个程序都把这些很常用的函数的实现包含在内的话,就会占用很多空间

有一个很好的办法,把这些常用的函数实现提取成单独的文件(动态链接库),放在某个地方,一个程序需要使用某个函数的时候再去加载对应的库,这样就能节省很多空间

示例

// main.c![1553306805246.jpg](https://upload-images.jianshu.io/upload_images/11850278-1d763cd2c7d3f022.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

void hello();
int main()
{
    hello();
    return 0;
}
// hello.c
#include <stdio.h>

void hello()
{
    printf("Hello World from hello.c\n");
}

编译测试一下
gcc main.c hello.c -o main && ./main

正常输出,没毛病

接下来将hello.c编译成动态链接库试一试
gcc hello.c -shared -o libhello.so

可以看到编译出了libhello.so

接下来编译main.c,并且制定使用libhello这个库,在当前目录查找库文件
gcc main.c -lhello -L. -o main

运行一下试试

没毛病

试试把libhello.so的名字改了,或者移动到其他地方,让main找不到动态库

可以看到,程序的确找不到库了,不能正常输出

可以很明确的看出,程序是在运行时动态加载libhello.so库的,如果这个库被移动或者改名了,程序就不能正常运行

用ldd命令看看动态库的依赖
ldd ./main

可以看到这个程序的几个动态依赖

静态链接

简介

静态链接就是直接把所有运行时需要的库,全部包含进程序中,打包在一起,这样就不管外面的库怎么移动怎么改名怎么缺少,程序都可以运行

示例

还是之前的代码,将hello.c编译,但是不作链接
gcc -c hello.c -o hello.o && ll

生成的hello.o

再把hello.o打包成静态库文件
ar -r libhello.a hello.o && ll

生成的静态库文件

再来编译main.c并且把libhello.a静态链接进程序中
gcc main.c -lhello -L. -static -o main_static

运行结果一切正常,并且跟静态库已经没有关系了,删掉静态库程序依然可以运行


可以看出差别在哪

ldd命令看看
ldd ./main_static

哈,不是个动态可执行文件

小结

没有小结,自己看书去!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 动态链接,在可执行文件装载时或运行时,由操作系统的装载程序加载库。大多数操作系统将解析外部引用(比如库)作为加载过...
    小5筒阅读 5,567评论 0 3
  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,883评论 0 27
  • 第一章:编译和安装SCons第二章:简单编译第三章:编译相关的一些事情第四章:编译和链接库文件第五章:节点对象第六...
    仙灵儿阅读 12,025评论 0 3
  • 1.什么是库在windows平台和linux平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被...
    鹰击司马阅读 1,132评论 0 2
  • 你是否记得那一天,独自默默许下的愿 听完这首歌时,友人打来电话邀我晚上一同吃饭,我说,我需要敷个面膜,涂个防晒,拉...
    mp_mask阅读 479评论 0 2