静态库和共享库之间的区别是什么?

我使用Eclipse,有几个项目类型,包括静态库和共享库?其中一种比另一种有优势吗?


当前回答

共享库最显著的优点是,不管有多少进程在使用这个库,内存中只加载一份代码。对于静态库,每个进程都有自己的代码副本。这可能导致严重的内存浪费。

静态库的一个优点是所有东西都捆绑到应用程序中。因此,您不必担心客户端系统上是否有正确的库(和版本)可用。

其他回答

共享库最显著的优点是,不管有多少进程在使用这个库,内存中只加载一份代码。对于静态库,每个进程都有自己的代码副本。这可能导致严重的内存浪费。

静态库的一个优点是所有东西都捆绑到应用程序中。因此,您不必担心客户端系统上是否有正确的库(和版本)可用。

共享库是.so(或在Windows .dll中,或在OS X .dylib中)文件。所有与库相关的代码都在这个文件中,运行时使用它的程序会引用它。使用共享库的程序只引用它在共享库中使用的代码。

静态库是.a(在Windows中是.lib)文件。所有与库相关的代码都在这个文件中,它在编译时直接链接到程序中。使用静态库的程序从静态库中获取它所使用的代码的副本,并使其成为程序的一部分。[Windows也有.lib文件,用于引用.dll文件,但它们的作用与第一个相同]。

每种方法都有优缺点:

Shared libraries reduce the amount of code that is duplicated in each program that makes use of the library, keeping the binaries small. It also allows you to replace the shared object with one that is functionally equivalent, but may have added performance benefits without needing to recompile the program that makes use of it. Shared libraries will, however have a small additional cost for the execution of the functions as well as a run-time loading cost as all the symbols in the library need to be connected to the things they use. Additionally, shared libraries can be loaded into an application at run-time, which is the general mechanism for implementing binary plug-in systems. Static libraries increase the overall size of the binary, but it means that you don't need to carry along a copy of the library that is being used. As the code is connected at compile time there are not any additional run-time loading costs. The code is simply there.

就我个人而言,我更喜欢共享库,但当需要确保二进制文件没有许多难以满足的外部依赖时,例如c++标准库的特定版本或Boost c++库的特定版本,则使用静态库。

+---------------+---------------------------+------------------------------+
| properties    | Static library            | Shared library               |
+===============+===========================+==============================+
| Linking time  | It happens as the         | Shared libraries             |
|               | last step of the          | are added during             |
|               | compilation process.      | linking process              |
|               | After the program         | when executable              |
|               | is placed                 | file and libraries           |
|               | in the memory             | are added to the memory.     |
+---------------+---------------------------+------------------------------+
| Means         | Performed by linkers      | Performed by operating System|
+---------------+---------------------------+------------------------------+
| Size          | Static libraries are      | Dynamic libraries are        |
|               | much bigger in size,      | much smaller, because        |
|               | because external          | there is only one copy       |
|               | programs are built        | of dynamic library           |
|               | in the executable file.   | that is kept in memory.      |
+---------------+---------------------------+------------------------------+
| External file | Executable file will      | In shared libraries,         |
| changes       | have to be recompiled     | no need to recompile         |
|               | if any changes were       | the executable.              |
|               | applied to external files.|                              |
+---------------+---------------------------+------------------------------+
| Time          | Takes longer to execute   | It is faster                 |
|               | because loading into the  | because shared               |
|               | memory happens every time | library code is              |
|               | while executing.          | already in the memory.       |
+---------------+---------------------------+------------------------------+
| Compatibility | Never has a compatibility | Programs are dependent       |
|               | issue,since all code is   | on having a compatible       |
|               | in one executable module. | library.Dependent program    |
|               |                           | will not work if library     |
|               |                           | gets removed from the system |
+---------------+---------------------------+------------------------------+

对于静态库,代码由链接器从库中提取,并在编译/构建应用程序时用于构建最终的可执行文件。最终的可执行文件在运行时不依赖于库

对于共享库,编译器/链接器在构建应用程序时检查所链接的名称是否存在于库中,但不会将它们的代码移到应用程序中。在运行时,共享库必须可用。

C编程语言本身没有静态库或共享库的概念——它们完全是一种实现特性。

就我个人而言,我更喜欢使用静态库,因为它使软件分发更简单。然而,这一观点在过去曾引发大量(象征性的)流血冲突。

简化:

静态链接:一个大型可执行文件 动态链接:一个小的可执行文件加上一个或多个库文件(Windows上是.dll文件,Linux上是.so文件,macOS上是.dylib文件)