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

静态库和共享库有什么区别?

我使用Eclipse,有几个项目types,包括静态库和共享库? 一个人比另一个人有优势吗?

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

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

每种方法都有优点和缺点。

共享库减less了每个使用该库的程序中重复的代码量,从而保持二进制文件的小型化。 它也允许你用一个function相同的replace共享对象,但是可能增加了性能,而不需要重新编译使用它的程序。 然而,共享库的执行function和运行时的加载成本只需很小的额外成本,因为库中的所有符号都需要连接到它们所使用的东西上。 另外,共享库可以在运行时加载到应用程序中,这是实现二进制插件系统的一般机制。

静态库会增加二进制文件的整体大小,但这意味着您不需要携带正在使用的库的副本。 由于代码在编译时连接,所以没有任何额外的运行时加载成本。 代码就在那里。

就个人而言,我更喜欢共享库,但在需要确保二进制文件没有很多可能难以满足的外部依赖性(如特定版本的C ++标准库或特定版本的Boost C ++库)时使用静态库。

静态库就像书店,共享库就像一个库。 与前者一样,你可以将自己的书/function副本带回家; 与后者,你和其他人去图书馆使用相同的书/function。 所以任何想要使用(共享)库的人都需要知道它在哪里,因为你必须“去获取”书/function。 有了一个静态库,这本书/函数就是你自己的,并且保存在你的家庭/程序中,一旦你拥有了它,你就不会在意何时何地得到它。

简化:

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

静态库被编译为应用程序的一部分,而共享库不是。 当您分发依赖于共享库的应用程序时,库,例如。 MS Windows上的DLL需要安装。

静态库的优点是运行应用程序的用户不需要任何依赖关系 – 例如,他们不需要升级他们的任何DLL的DLL …缺点是你的应用程序的体积较大,因为你正在所有它需要的库。

除了导致更小的应用程序,共享库还提供了使用自己的,也许更好的版本的库的能力,而不是依赖于应用程序的一部分

对于静态库,代码由链接器从库中提取,并用于在编译/构build应用程序的位置生成最终的可执行文件。 最终的可执行文件在运行时对库没有依赖关系

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

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

就个人而言,我更喜欢使用静态库,因为它使软件分发更简单。 然而,这是一个意见,过去有多less(比喻)的血已经stream失了。

共享库最重要的优点是,无论有多less进程正在使用库,只有一个代码副本加载到内存中。 对于静态库,每个进程都获得自己的代码副本。 这可能会导致重大的内存浪费。

OTOH是静态库的一个优点,就是一切都捆绑到你的应用程序中。 因此,您不必担心客户端系统上可以使用正确的库(和版本)。

除了所有其他的答案之外,还有一件事没有提到的是解耦:

让我谈谈一个我一直在处理的真实世界生产代码:

一个非常大的软件,由大于300个项目(包括visual studio)构成,大部分都是静态库,最后所有的链接都集成在一个巨大的可执行文件中,最后出现以下问题:

链接时间非常长 你最终可能会超过15分钟的链接,比如说10秒的编译时间 – 有些工具在他们的膝盖上有这么大的可执行文件,比如内存检查工具,它们必须对代码进行检查。 你可能会陷入被认为是愚蠢的极限。

更麻烦的是你的软件解耦:在这个真实世界的例子中,每个项目的头文件可以从任何其他项目中重新获得。 因此,一个开发者添加依赖关系是非常容易的。 这只是包括头,因为链接在结尾将allwawsfind符号。 它结束了可怕的自行车依赖和完全混乱。

使用共享库时,需要额外的工作,因为开发人员必须编辑项目构build系统以添加依赖库。 我观察到共享库代码倾向于提供更干净的代码API。