gpt4 book ai didi

c - C中的动态链接库

转载 作者:行者123 更新时间:2023-12-02 09:10:14 24 4
gpt4 key购买 nike

我对 C 中的动态链接库有一些疑问。

Q1。 enter image description here

我的课本用一张图来说明DLL是如何工作的,并且似乎复制了libvector.solibc.so的一些重定位和符号表信息(箭头附在他们的一边),但是每当汇编程序遇到引用最终位置未知的对象时,它会生成一个重定位条目,告诉链接器在将目标文件合并到可执行文件中时如何修改引用。对于libc.so,一切都是已知的(它有所有的定义),所以libc.so不应该有任何重定位入口,不是吗

Q2。我的教科书是这样说的:

“内存中共享库的 .text 部分的单个副本可以由不同的运行进程共享”,

假设我有一个使用 printf 的程序。 printf.text 部分是永远保留在 RAM 中,还是在第一个程序完成时从 RAM 中逐出,并在第二个进程使用 时加载到 RAM 中>printf 又一次?如果是后者,那么 printf.text 部分被驱逐并多次加载到 RAM 中是不是非常低效,因为我们有多个进程可以在后台运行?

最佳答案

Q1:我觉得你提供的图表是正确的。是main2正在 build 中; libvector.so的重定位和符号表信息和 libc.so正在被复制,以便最终的可执行文件可以使用它们。从main2的角度、函数、常量等来自 libclibvector正在添加,所以我同意你的教科书,即libvector.so的重定位和符号表信息。和 libc.so正在被复制。

Q2:您只提出了两个极端:“永远留在 RAM 中”或“当第一个程序完成时从 RAM 中逐出”。几乎可以肯定,只要某些最近运行的进程使用了​​库的可共享部分,它们就会保留在 RAM 中。操作系统将使用的一个典型策略是 LRU 算法,用于从 RAM 中逐出“未使用”的东西,但只有当它想加载到 RAM 中的内容超过了可用空间时。因此,在一台使用频率较低的机器上,几乎所有东西都可能在 RAM 中停留很长时间;但是在一台负担过重的机器上,操作系统会不断地从 RAM 中丢弃它很快就会再次需要的东西。但即便如此,有些东西的使用频率如此之高,它们不太可能达到 LRU 阈值,因此您可能会在 RAM 中长期保留某些东西,即使大多数东西都被逐出也是如此。

Q1 跟进: 在回答您评论中的问题时:正确:main2.c 中没有任何内容定义在 libc 中找到的函数.正因为如此,链接器需要为 printf() 复制重定位和符号表信息。来自 libc.so ,所以当main2被执行,libc.so也被加载。

更详细:

printf()可能从 main2.c调用 ,但是printf()stdio.h声明并且定义在例如printf.c [1] 并编译libc.so ; main2.c可以编译 因为编译器可以看到 printf() 的签名(在 stdio.h 中),但要构建 main2 (可执行文件),已在 libc.so 中编译的代码需要与 main2.o 进行链接 (中间目标文件)。 ld通过复制导致执行 main2 的引用来做到这一点动态加载 libc.so . [2]

[1] 编译器在标准库函数的定义方式上有所不同; gcc有一个文件 printf.c它定义了 printf() (它实际上是传递给 vfprintf() );其他编译器可能会做不同的事情——但是库的全部意义在于你永远不需要查看 printf()定义和其他图书馆功能;您只需要来自适当的 .h声明文件以便知道如何在您自己的文件中调用 .c文件。

[2] 或者,如果您构建一个静态链接的可执行文件,则代码(不仅仅是符号表)会从库文件复制到可执行文件中正在构建,即使在没有 .so 的机器上,该可执行文件也可以运行文件存在。动态链接还是静态链接更适合构建给定的可执行文件取决于几个因素。

关于c - C中的动态链接库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53199913/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com