当前位置: 首页 > 面试题库 >

共享库(.so),静态库(.a)和DLL(.so)之间的区别?

欧阳勇军
2023-03-14
问题内容

我参与了有关Linux库的一些辩论,并想确认一些事情。

以我的理解(如果我做错了请纠正我,稍后我将编辑我的文章)在构建应用程序时有两种使用库的方式:

  1. 静态库(.a文件):在链接时,会将整个库的副本放入最终应用程序中,以便调用方应用程序始终可以使用库中的功能
  2. 共享对象(.so文件):在链接时,仅通过相应的标头(.h)文件针对其API验证了对象。该库直到需要运行时才真正使用。

静态库的明显优点是它们允许整个应用程序独立运行,而动态库的优点是可以替换“
.so”文件(即:由于安全性而需要更新的情况)错误),而无需重新编译基本应用程序。

我听说有人对共享库和动态链接库(DLL)进行了区分,即使它们都是“
.so”文件。在Linux或任何其他POSIX兼容操作系统(即MINIX,UNIX,QNX等)上进行C / C
++开发时,共享库和DLL之间是否有区别?有人告诉我(到目前为止)一个关键的区别是共享对象仅在运行时使用,而DLL的共享必须首先在应用程序中使用dlopen()调用来打开。

最后,我还听到一些开发人员提到“共享档案”,据我了解,共享档案本身也是静态库,但从未被应用程序直接使用。相反,其他静态库将链接到“共享档案”,以将某些(但不是全部)功能/资源从共享档案中拉到正在构建的静态库中。

预先感谢大家的帮助。

在向我提供这些术语的上下文中,必须学习Linux的一组Windows开发人员实际上使用了错误的术语。
我试图纠正它们,但是(不正确的)语言规范卡住了。

  1. 共享库:程序启动时自动链接到程序的库,并且作为独立文件存在。该库在编译时包含在链接列表中(即:LDOPTS+=-lmylib对于名为的库文件mylib.so)。 该库必须在编译时以及应用程序启动时存在。
  2. 静态库:静态库,在构建时就合并到单个程序中(包含大型应用程序),该单个应用程序包含应用程序代码和在构建程序时自动链接到程序中的库代码,而最终的二进制文件则同时包含两者主程序和库本身作为单个独立的二进制文件存在。该库在编译时包含在链接列表中(即:LDOPTS+=-lmylib对于名为mylib.a的库文件)。 该库必须在编译时存在。
  3. DLL:本质上与共享库相同,但不是在编译时包含在链接列表中,而是通过dlopen()/ dlsym()命令加载该库,因此不需要在构建时就存在该库来进行程序编译。 同样,该库不需要在应用程序启动或编译时出现(必需) ,因为仅在进行dlopen/ dlsym调用时才需要。
  4. 共享存档:本质上与静态库相同,但是使用“导出共享”和“ -fPIC”标志进行编译。该库在编译时包含在链接列表中(即:LDOPTS+=-lmylibS对于名为的库文件mylibS.a)。两者之间的区别是,如果共享库或DLL希望将共享归档文件静态链接到其自己的代码,并且能够使共享库中的函数可用于其他程序,而不仅仅是使用它们,则需要此附加标志。 DLL内部。当有人为您提供静态库并且您希望将其重新打包为SO时,这很有用。 该库必须在编译时存在。

附加更新

DLL”和“ shared library
之间的区别只是我当时工作的公司中的一种(懒惰,不准确的)口语(Windows开发人员被迫转移到Linux开发,并且这个术语陷入僵局),并遵循上述说明。

另外,在S“共享档案”的情况下,库名后的尾随“ ”文字只是该公司的惯例,而不是整个行业。


问题答案:

我一直认为DLL和共享对象是同一事物的不同术语-Windows将它们称为DLL,而在UNIX系统上,它们是共享对象,并且通用术语-动态链接库-
涵盖了这两个对象(甚至包括在UNIX上打开.so称为dlopen()“动态库”。

它们确实仅在应用程序启动时链接,但是您对头文件的验证概念不正确。头文件定义了用于编译使用该库的代码所需的原型,但是在链接时,链接器会在库本身内部进行查找,以确保所需的功能确实存在。链接器必须在链接时在某处找到函数体,否则会引发错误。它还在运行时执行此操作,因为正如您正确指出的那样,自程序编译以来,库本身可能已更改。这就是为什么ABI稳定性在平台库中如此重要的原因,因为ABI的改变破坏了针对旧版本编译的现有程序。

静态库只是直接从编译器中提取的目标文件包,就像在项目编译过程中要构建自己的对象库一样,因此静态库以完全相同的方式被拉入并馈送到链接器,未使用的位是以完全相同的方式掉落。



 类似资料:
  • 本文向大家介绍静态库和共享库之间的区别,包括了静态库和共享库之间的区别的使用技巧和注意事项,需要的朋友参考一下 在编程上下文库中是一种具有某种代码的东西,这些代码已经过预编译,可以在任何程序中重新使用以实现某些特定功能或特性。 现在,根据该代码库的执行和存储,将其分为两种类型,即静态库和共享库。 以下是静态库和共享库之间的重要区别。 序号 要点 静态库 共享库 1 定义 静态库是一个库,其中执行文

  • 问题内容: 标题中的问题很多:就操作系统级别的实现而言,共享库和dll有何不同? 我之所以这样问,是因为我最近阅读了有关扩展Python的页面,其中指出: Unix和Windows使用完全不同的范例来运行时加载代码。在尝试构建可以动态加载的模块之前,请了解系统的工作方式。 在Unix中,共享对象(.so)文件包含程序要使用的代码,以及它希望在程序中找到的函数和数据的名称。将文件加入程序后,文件代码

  • 我知道一个文件是一种动态库(很多线程可以共享这样的库,所以不需要在内存中有多个副本)。但是和?这些都是静态库吗? 如果动态库比静态库有很大的优势,为什么仍然有很多静态库?我应该什么时候尝试将代码构建到或中?

  • 问题内容: 说我有a.so和b.so。我是否可以将c.so生成为具有a和b导出的所有功能的单个共享库,当然可以解决所有内部依赖关系(即a.so调用的b.so的所有功能,反之亦然)? 我试过了 但这不起作用。 如果我在aa和ba中归档ao和bo(也不应修改ao和bo),也是如此 谢谢 问题答案: 除了AIX之外,在所有UNIXen上实际上都不可能将多个共享库合并为一个:链接器将.so视为“最终”产品

  • 问题内容: 我有一个项目,其中有一个静态库,另一个有我的实际共享库。我的目标是链接到。在Linux / BSD上可以吗?尝试创建测试程序时,出现以下错误: ./prog1:/usr/local/lib/libtestlib.so.1.0:未定义的符号’‘ 我的猜测是,这是因为libhelper.a不是用while 编译的。使用共享库(也依赖于静态库)来构建程序的正确方法是什么? 谢谢! 问题答案:

  • 问题内容: 最近,我不得不在Ubuntu系统上做一些次要的编程(在这个系统上我是一个非常低级的初学者),我真的只是对makefile有所了解。 我注意到,告诉链接程序要包括哪些库的参数始终为-l {library name},其中在/ usr / lib文件夹中相应的库将是名为“ lib {library name} .a”的文件。 我想知道:这是公约吗?我以为我需要键入-llibNAME来找到一