Summary
1)链接的定义:将指标文件最终链接为可执行程序
2)链接的 2 种形式:
- 动态链接:
指标文件会被间接 * 链接 * 进可执行程序
。slib.a
被删掉后,程序仍旧能够运行 - 动静链接:
程序启动后才动静加载指标文件
。dlib.so
被删掉后,程序无奈运行
3)动态链接和动静链接形式的抉择:
- 动态链接:实用于比较简单的程序,开发进去不须要变动的,比方纯本地的记事本这种;把
所有指标文件都编到可执行程序里,可能会导致可执行程序很大
。 - 动静链接:一个大型软件的各个模块,如果采纳动静库的模式,
哪个模块须要更新了,只须要批改这个模块,而后把 dlib.so 传到服务器上
。用户在应用软件时,间接去服务器上拿这一个库更新下就能够了,而不须要更新整个程序。
链接过程简介
问题:工程里的每个 .c 源文件
在编译后都会生成 指标文件.o
,那这些.o 文件怎么生成最终的 可执行程序.out
呢?
答:链接器
的次要作用是把 各个模块间互相援用的局部解决好
,使得各个模块之间能失常的连接。
1、动态链接
- 链接器在
链接时将库的内容间接退出到可执行程序中
- 动态库的创立和应用
1)生成动态库指标文件
:gcc -c slib.c -o slib.o
2)生成动态库
:ar -q slib.a slib.o(输入:ar:creating slib.a;ar 指的是 archive,把前面列出的所有指标文件全都打包进 slib.a 中
)
3)应用动态库编译
:gcc 20-1.c slib.a -o 20-1.out(应用动态库进行编译)
2、动静链接
- 可执行程序在
运行时才动静加载库进行链接
(运行时才去找我须要的 symbol) 库的内容不会进入到可执行程序中
// dlib.c
char* name()
{return "Dynamic Lib";}
int add(int a, int b)
{return a+b;}
// 20-2.c
#include <stdio.h>
#include <dlfcn.h>
int main()
{void* pdlib = dlopen("./dlib.so", RTLD_LAZY); // pdlib 指向了目录下 dlib.so 这个动静库
// 这个关上就相当于一个加载到内存里的指针
char* (*pName)(); // 定义函数指针
int (*pAdd)(int, int);
if(NULL != pdlib)
{pName = dlsym(pdlib, "name"); // 查找 pdlib 指向的动静库里的函数
pAdd = dlsym(pdlib, "add");
if(NULL != pName && NULL != pAdd)
{printf("Name: %s\n", pName());
printf("Ret: %d\n", pAdd(2, 3));
}
dlclose(pdlib); // 敞开 pdlib 指向的动静库
}
else
{printf("Cannot open dynamic lib...");
}
}
// linux 命令
gcc -shared dlib.c -o dlib.so : 创立了动静库 dlib.so
gcc 20-2.c -ldl -o a.out : 应用动静库创立了可执行程序 a.out
./a.out:执行可执行程序
留神:-ldl 通知编译器,这个程序用动静库的形式来编译
,咱们的程序依赖动静库。如果动静库dlib.so 删掉了,这个程序就运行不起来了
,输入 cannot open,因为 a.out 每次执行时须要去动静库里找 symbol 的(我要用啥,我每次得去你的仓库里拿),库都没了,天然找不到了。
本文总结自“狄泰软件学院”唐佐林老师《C 语言进阶课程》。
如有错漏之处,恳请斧正。