我从书( Expert C编程:深层C秘密“Peter Van Der Linden )中了解到,有一些特定的库需要动态链接;这些库是哪些库,为什么它们是强制动态链接?(更具体地说,在GNU / Linux系统上)
答案 0 :(得分:2)
这些库是哪些
所有UNIX系统都保证向后兼容;也就是说,在旧系统上构建的二进制文件将继续工作并且更新的系统。但是这种保证仅适用于与系统库动态链接的二进制文件。
为什么他们强制性地动态链接
限制已经到位,因为用户级程序通常不进行直接系统调用,而是调用libc包装程序。因此,如果系统库也更新,UNIX供应商可以自由地对syscall接口进行不兼容的更改(例如修复错误)。通常,这种更改仅在升级到新的OS版本时发生,例如,从Solaris
2.6到2.7。
Linux上的图片比我上面描述的更复杂,因为单个版本的glibc
由大约200多个单独的二进制文件组成,所有二进制文件都必须与完全匹配。静态链接一个这样的部分,然后在其他部分不匹配的系统上运行将产生不可预测的结果;经常在libc
的某处发生崩溃。
执行摘要:永远不会将UNIX系统库静态链接到您的可执行文件中,除非您知道自己在做什么并且非常有充分理由这样做。
答案 1 :(得分:1)
POSIX允许dlopen
和dlsym
函数根据需要依赖于实现定义的构建条件,并且通常这些条件是程序必须是动态链接的,或者如果它是静态链接的,使用等效的-rdynamic
链接器选项。因此,依赖于动态加载模块的某些库很可能只能在动态链接程序中工作,具体取决于您的操作系统。
除此之外,只要你遵守标准的要求一致的程序,静态链接就不适用于你想要的任何库。如果您开始依赖使用相同名称替换标准函数和自己的函数的hack,那么同一程序的静态和动态链接版本之间的行为可能会有所不同。这是未定义行为的一种表现形式。
还应该注意的是,glibc在静态链接方面存在许多问题。即使在静态链接时,使用glibc的程序也会动态加载libnss_*.so
库来处理passwd文件/ NIS / DNS查找/等。 glibc中还会定期断开静态链接支持。例如,我最近在glibc函数中遇到了故障,需要知道pid / tid,因为主线程的线程描述符未在静态链接二进制文件中正确初始化。如果你想在Linux上使用静态链接,我强烈建议你选择一个非glibc libc。