强制性dynamic链接库

我从Peter Van Der Linden的书( Expert C programming:deep C secrets )中学习到,有一些特定的库需要dynamic链接;这些库是什么,为什么强制dynamic链接?(更具体地说,GNU / Linux系统)

这些库是哪个?

所有的UNIX系统都保证向后兼容; 也就是说,在较旧的系统上构建的二进制文件将继续工作并且更新的系统。 但是这个保证只能用于与系统动态链接的二进制文件。

为什么他们强制动态链接

限制是有原因的,因为用户级程序通常不会直接进行系统调用,而是调用libc包装例程。 因此,UNIX系统供应商可以自由地对系统调用接口进行不兼容的修改(例如修复一个bug),前提是系统库也要更新。 通常只有在升级到新的操作系统版本时才会发生这种变化,例如从Solaris 2.6升级到2.7。

Linux上的图片比我上面描述的要复杂得多,因为单个版本的glibc由大约200多个单独的二进制文件组成,所有的二进制文件都必须完全匹配。 静态链接一个这样的部分,然后在其他部分不匹配的系统上运行将产生不可预知的结果; 经常在libc某个地方崩溃。

执行摘要: 不要将UNIX系统库静态链接到可执行文件中,除非您知道自己在做什么,并且有充分的理由这么做。

POSIX允许dlopendlsym函数是否按照所期望的那样工作,取决于实现定义的构建条件,通常这些条件是程序必须是动态链接的,或者如果是静态链接的,则相当于-rdynamic链接器选项。 所以一些依靠动态加载模块的库很可能只能在动态链接的程序中工作,这取决于你的操作系统。

除此之外, 只要你遵守符合标准的程序的要求,静态链接不应该与你想要的任何图书馆一起工作。 如果你开始依靠用相同名称替换标准函数的功能,那么同一个程序的静态和动态链接版本的行为可能会有所不同。 这是未定义行为的一种表现。

还应该注意的是,glibc有一些静态链接的问题。 即使在静态链接时,使用glibc的程序也会动态加载libnss_*.so库来处理passwd文件/ NIS / DNS查找/等等。 在glibc中也有周期性的静态链接支持。 比如我最近在一个glibc函数中遇到了错误,这个函数需要知道由于主线程的线程描述符没有在静态链接二进制文件中正确初始化而导致的pid / tid。 如果你想在Linux上使用静态链接,我强烈建议选择一个非glibc libc。