Difference between static and shared libraries?
静态库和共享库之间有什么区别?
我使用Eclipse,有几个项目类型,包括静态库和共享库?一个比另一个有优势吗?
共享库是.so(或Windows.dll或OS X.dylib)文件。与库相关的所有代码都在这个文件中,并且在运行时由使用它的程序引用。使用共享库的程序只引用它在共享库中使用的代码。
静态库是.a(或在windows.lib中)文件。所有与库相关的代码都在这个文件中,并且在编译时直接链接到程序中。使用静态库的程序从静态库中获取所用代码的副本,并将其作为程序的一部分。[Windows还有用于引用.dll文件的.lib文件,但它们的作用与第一个文件相同]。
每种方法都有优缺点。
共享库减少了使用库的每个程序中重复的代码量,从而使二进制文件保持较小。它还允许您用功能等效的对象替换共享对象,但可能会增加性能优势,而无需重新编译使用它的程序。但是,共享库在执行函数时会有一个很小的额外成本以及运行时加载成本,因为库中的所有符号都需要连接到它们使用的对象上。此外,共享库可以在运行时加载到应用程序中,这是实现二进制插件系统的一般机制。
静态库会增加二进制文件的总大小,但这意味着您不需要携带正在使用的库的副本。由于代码是在编译时连接的,因此没有任何额外的运行时加载成本。代码就在那里。
个人而言,我更喜欢共享库,但是当需要确保二进制文件没有很多可能难以满足的外部依赖性时,使用静态库,如C++标准库的特定版本或Boost C++库的特定版本。
静态库就像书店,共享库就像…图书馆。对于前者,您可以将自己的书籍/功能副本带回家;对于后者,您和其他所有人都可以到图书馆使用相同的书籍/功能。所以任何想使用(共享)库的人都需要知道它在哪里,因为你必须"去获取"这本书/函数。有了静态库,这本书/功能就归你所有了,你把它放在家里/程序里,一旦你拥有了它,你就不在乎它在哪里或什么时候得到。
简化:
- 静态链接:一个大型可执行文件
- 动态链接:一个小的可执行文件加上一个或多个库文件(Windows上的.dll文件,Linux上的.so文件,MacOS上的.dylib文件)
对于静态库,代码由链接器从库中提取,用于在编译/构建应用程序时构建最终的可执行文件。最终可执行文件在运行时不依赖库
对于共享库,编译器/链接器会在构建应用程序时检查与之链接的名称是否存在于库中,但不会将其代码移动到应用程序中。在运行时,共享库必须可用。
C编程语言本身没有静态或共享库的概念——它们完全是一个实现特性。
就个人而言,我更喜欢使用静态库,因为它使软件分发更简单。然而,这是一种观点,过去曾有许多(比喻性的)血液流出。
静态库是作为应用程序的一部分编译的,而共享库则不是。当您分发依赖共享库的应用程序时,需要安装库,例如MS Windows上的dll。
静态库的优点是,运行应用程序的用户不需要依赖项,例如,他们不必升级任何内容的DLL。缺点是您的应用程序的大小更大,因为您将它与它需要的所有库一起交付。
除了导致更小的应用程序之外,共享库还为用户提供了使用自己的库(可能是更好的库)版本的能力,而不是依赖于作为应用程序一部分的库版本。
共享库的最大优点是,不管有多少进程在使用该库,内存中只加载了一个代码副本。对于静态库,每个进程都有自己的代码副本。这会导致严重的内存浪费。
Otoh,静态库的一个优点是,所有东西都捆绑到应用程序中。因此,您不必担心客户机的系统上会有合适的库(和版本)。
除所有其他答案外,还有一件事尚未提及,那就是脱钩:
让我来谈谈我一直在处理的一个现实世界的生产代码:
一个非常大的软件,由超过300个项目组成(使用Visual Studio),主要构建为静态库,最后在一个巨大的可执行文件中链接在一起,最终会出现以下问题:
-链接时间非常长。你可能会得到超过15分钟的链接,比如10秒的编译时间-有些工具拥有如此大的可执行文件,比如必须检测代码的内存检查工具。你可能会陷入被视为傻瓜的极限。
更麻烦的是您的软件的分离:在这个现实世界的例子中,每个项目的头文件都可以从其他项目中获取。因此,对于一个开发人员来说,添加依赖关系是非常容易的;它只是包含头部,因为最后的链接将总是找到符号。结果是可怕的循环依赖和彻底的混乱。
对于共享库,这是一项额外的工作,因为开发人员必须编辑项目构建系统以添加依赖库。我注意到共享库代码倾向于提供更干净的代码API。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ------------------------------------------------------------------------- | +- | Shared(dynamic) | Static Library (Linkages) | ------------------------------------------------------------------------- |Pros: | less memory use | an executable, using own libraries| | | | ,coming with the program, | | | | doesn't need to worry about its | | | | compilebility subject to libraries| ------------------------------------------------------------------------- |Cons: | implementations of | bigger memory uses | | | libraries may be altered | | | | subject to OS and its | | | | version, which may affect| | | | the compilebility and | | | | runnability of the code | | ------------------------------------------------------------------------- |