Summary
1)链接的定义:将目标文件最终链接为可执行程序
2)链接的2种方式:
- 静态链接:
目标文件会被直接*链接*进可执行程序
。slib.a
被删掉后,程序依旧可以运行
文章图片
- 动态链接:
程序启动后才动态加载目标文件
。dlib.so
被删掉后,程序无法运行
文章图片
- 静态链接:适用于比较简单的程序,开发出来不需要变动的,比如纯本地的记事本这种;把
所有目标文件都编到可执行程序里,可能会导致可执行程序很大
。 - 动态链接:一个大型软件的各个模块,如果采用动态库的形式,
哪个模块需要更新了,只需要修改这个模块,然后把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.cslib.a -o 20-1.out (使用静态库进行编译)
文章图片
- 可执行程序在
运行时才动态加载库进行链接
(运行时才去找我需要的symbol) 库的内容不会进入到可执行程序中
文章图片
// dlib.c
char* name()
{
return "Dynamic Lib";
}int add(int a, int b)
{
return a+b;
}
// 20-2.c
#include
#include 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进阶】20、链接过程简介】本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。
推荐阅读
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- C/C++|C/C++ basis 02
- Qt实战|Qt+OpenCV联合开发(二十一)--图像翻转与旋转
- Qt实战|Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取
- Qt实战|Qt+OpenCV联合开发(十三)--通道分离与合并
- opencv|Qt+OpenCV联合开发(十六)--图像几何形状绘制
- Qt实战|Qt+OpenCV联合开发(十七)--随机数与随机颜色
- SNAT的MASQUERADE地址选择与端口选择
- IPTABLES的连接跟踪与NAT分析
- IPVS分析