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

成都开发网站建设广州微信小程序开发制作公司

成都开发网站建设,广州微信小程序开发制作公司,婚纱网站设计首页,免费网站建设自助建站参考动态链接 - 知乎 加上我自己的理解,比较好懂,但可能在细节方面有偏差,但总体是一致的 静态链接的背景 静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率&#xf…

参考动态链接 - 知乎

加上我自己的理解,比较好懂,但可能在细节方面有偏差,但总体是一致的

静态链接的背景

静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率,原先现在程序规模也随之扩大。
但静态链接的缺点也暴露出来:浪费内存、磁盘空间、模块更新困难(耦合性太强)。

内存与磁盘空间

静态链接在计算机早期还是比较流行的,但是到了后面,其缺点也非常明显。比如浪费内存和磁盘空间,更新模块困难等。

一个文件的转换进程

hello.c(源程序[文本])->预处理器(cpp)->hello.i(修改了的源程序[文本])->编译器(ccl)->hello.s(汇编程序[文本])->汇编器(as)->hello.o(可重定位目标程序[二进制])->链接器(ld)->hello(可执行目标程序[二进制])

只需要注意:

hello.c:源文件

hello.o:由hello.c编译而来

hello(可执行目标程序[二进制]),最终执行文件。

比如我有a.cpp ,a.h,b.cpp c.cpp四个文件

a.cpp 定义了一个函数sayHello

#include <iostream>
void sayHello(){std::cout<<"hello world!";
}

a.h

#ifndef UNTITLED1_A_H
#define UNTITLED1_A_Hvoid sayHello();#endif //UNTITLED1_A_H

b.cpp 调用了a的函数sayHello

#include "a.h"
int main(){sayHello();
}

c.cpp 调用了a的函数sayHello

#include "a.h"
int main(){sayHello();
}

静态链接

如果运行b那么就会结合b.o,以及其调用的a.o生成可执行文件。c运行会另外调用 c.o,a.o生成可执行文件,此时可执行文件可以认为长这样

#include <iostream>
void sayHello(){std::cout<<"hello world!";
}
int main(){sayHello();
}

此时a.o重复了两次,但这两个a.o保存了相同的内容,浪费内存和磁盘。

再比如Program1 & Program2分别包含Program1.o和Program2.o两个模块,并且还共用了Lib.o这个模块。静态链接下,P1和P2都用到了Lib.o这模块,所以它们同时在链接输出的可执行文件P1和P2有两个副本,当同时运行两个程序,Lib.o在磁盘和内存中都有两个副本,浪费空间。

程序开发与发布

静态链接另一个问题是对程序的更新,部署和发布也会很麻烦,我如果在a中更新了sayHello,那么生成的b,c可执行文件里的sayHello还是老的,需要重新连接,很麻烦耦合度很高。

程序有任何模块更新,整个程序就要重新链接,发布给用户,

动态链接

dll文件和so文件

dll文件和so文件都是动态链接库,也叫共享对象文件

动态链接原理

动态链接库就是将程序模块相互独立的分隔开来,形成独立的文件,不再将它们静态地链接到一起。简单而言就是对那些组成程序目标文件的链接,等到程序运行时才进行链接,也就是把链接的过程推迟到运行时才进行,这就是动态链接的基本思想

动态链接没有提前链接的过程,但一般文件都是动态和静态链接结合使用,也有生成可执行文件这一步。

比如我编译a.cpp为共享对象文件a.so,还有a.h

b.cpp为c.o,此时我运行生成可执行文件,生成时侦测到sayHello为动态链接的实现,所以就不执行链接(如果侦测到为静态文件,那么就还是老样子进行链接)

b可执行文件执行时,遇到sayHello,就去动态库so中找这个函数的实现位置,这个找的位置有几类,我们经常用的是一个环境变量,叫LD_LABRARY_PATH,假设这里找到了,找到之后就将a.so加载到内存,链接,进行执行。

c执行时再用到a.so,此时a.so以及被加载到了内存中,所以不用再重新加载了,直接链接就能使用了。

那也就说明了动态链接的其他特点:

动态运行b.cpp之前必须要有a.so和a.h才能运行,所需的动态库本地必须齐全。

动态链接库的存储位置以及名称

lib文件的名称,要和头文件相呼应,不然怎么找对应的lib呢。

 比如

cudnn.h对应libcudnn.so

cudnn_adv_infer.h对应libcudnn_adv_infer.so等等

每一个头文件都要有唯一的一个对应的so文件。

一般so文件会存在lib下,头文件存在include下

如cuda11.6

 

 可以看到

再比如我们c++原生的一些实现

头文件也是在include下,可以看到我们的老熟人头文件iostream等等

 

模块

静态链接中,整个程序最终只有一个可执行文件,它是一个不可以分割的整体,但是在动态链接下,一个程序被分成了若干个文件,有程序的主要部分,即可执行文件(Program1)和
程序所依赖的共享对象(Lib.so),很多时候把这些部分叫做模块,即动态链接下的可执行文件和共享对象都可以看做是程序的一个模块

当程序模块Program1.c被编译成Program1.o时,编译器还不不知道foobar函数的地址,当链接器将Program1.o链接成可执行文件时,这时候链接器必须确定Program1.o中所引用的foobar函数的性质。

  • 如果foobar是一个定义与其它静态目标模块中函数,那么链接器将会按照静态链接的规则,将Program1.o中的foobar地址引用重定位
  • 如果foobar是一个定义在某个动态共享对象中的函数,那么链接器就会将这个符号的引用标记为一个动态链接的符号,不对它进行地址重定位,把这个过程留到装载时再进行

程序如何找到用到的动态库以及查看用到的动态库

动态库的搜索顺序如下:

  • LD_PRELOAD环境变量指定库路径
  • -rpath链接时指定路径
  • LD_LIBRARY_PATH环境变量设置路径
  • /etc/ld.so.conf配置文件指定路径
  • 默认共享库路径,/usr/lib,lib

应该就是按顺序一个一个寻找,直到找到满足要求的实现的动态库为止。

程序是如何找到动态库的? | 守望的个人博客

http://www.yayakq.cn/news/760821/

相关文章:

  • 网站建设及维护业务服务合同wordpress 分页显示
  • 网站名字重复网站建设四个阶段
  • 淘客网站备案教程网站设计价钱
  • 网站title如何写网络安全防护软件
  • 可以查企业的网站快速学会做网站
  • 网站建设设计维片手机html5网站源码
  • 网站空间的参数网站建设文编
  • 广东做陶瓷的网站如何才能做好网络营销
  • 手机网站是什么谷歌外贸平台有哪些
  • 网站优化案例分析小吃加盟网站大全
  • 网站建设logo尺寸河北外贸网站建设
  • 沈阳市城乡建设网站东莞网站建设(推荐乐云践新)
  • 旅游网站前台怎么做网站项目建设管理
  • 如何建设一个社交网站网站建设专业性的评价内容
  • 高级营销型网站建设网络营销软件价格
  • 网站备案必须做前置审批吗环球贸易网官网
  • 湘潭网站建设设计仙桃网站建设公司
  • 亚马逊欧洲站vat怎么申请施工企业适用什么标准
  • 建设银行苏州网站aspcms网站模板
  • 唐山建设招聘信息网站自己设计logo网站
  • 欢乐海岸网站建设洛阳网最新消息
  • php网站开发案例网上购物网站建设公司
  • 做重视频网站wordpress dynamo
  • 哪个网站可以做行测题目公众号链接制作
  • 安宁市建设局网站网页模版下载器
  • 网站开发多久网站设计遇到的问题
  • 如果做微商需不需要开个网站网站开发最强工具
  • 做车展招商的网站店面设计原则
  • 消费全返的 微网站开发网站文章图片如何跳转
  • 家教网站制作高端企业网站公司