【发布时间】:2014-05-31 14:51:59
【问题描述】:
根据this expert,
动态加载是指在启动后将可执行文件或库映射(或较少复制)到进程的内存中。 动态链接是指在编译后解析符号 - 将它们的名称与地址或偏移量相关联。
因此,相应地:静态加载是指在可执行文件或库启动之前将其映射到内存中,静态链接是指在编译时解析符号。 p>
现在,当您对库进行静态加载和静态链接时,库的二进制代码会附加到您的二进制代码中,并且(函数和变量)引用您对库的二进制代码已修补(不确定这是否是正确的术语),以便它们指向正确的位置。
这意味着在静态链接一个函数调用之前
foo()
会给你(在 x86 ASM 中),除其他外,如下指令:
call 0x00000000
在静态链接之后,你会得到类似的东西:
call 0x00001043
其中 0x00001043 是链接器输出的二进制代码中函数 foo 的入口点。
现在,当您进行动态加载和动态链接时,您将通过函数指针调用库函数: typedef int (*fun_ptr)(void);
library = dlopen("mylib.so");
fun_ptr foo = dlsym(library, "foo");
foo();
这种机制也是 C++ 虚方法的工作方式。要调用的方法的地址在运行时通过使函数指针指向实例的方法部分(存储在所谓的 vtable 中)来解析。
我的问题是这样的:
当您对共享库(对于上下文,比如说 linux 中的 .so)进行 静态加载 和 动态链接 时,此链接是否会修补我的二进制文件的引用,例如在静态加载和链接场景中,还是像动态加载和链接和C++虚方法那样通过函数指针工作?
【问题讨论】:
标签: linker static-linking dynamic-linking