我参与了有关Linux库的一些辩论,并想确认一些事情。
根据我的理解(如果我做错了,请纠正我,稍后我将编辑我的文章)在构建应用程序时有两种使用库的方法:
- 静态库(.a文件):在链接时,会将整个库的副本放入最终应用程序中,以便调用方应用程序始终可以使用库中的功能
- 共享对象(.so文件):在链接时,仅通过相应的标头(.h)文件针对其API对对象进行了验证。该库直到需要运行时才真正使用。
静态库的明显优点是它们允许整个应用程序独立运行,而动态库的优点是可以替换“ .so”文件(即:由于安全原因需要更新)错误),而无需重新编译基本应用程序。
我听说有人对共享库和动态链接库(DLL)进行了区分,即使它们都是“ .so”文件。在Linux或任何其他POSIX兼容操作系统(即MINIX,UNIX,QNX等)上进行C / C ++开发时,共享库和DLL之间是否有区别?有人告诉我(到目前为止)一个关键的区别是共享对象仅在运行时使用,而DLL的共享必须首先在应用程序中使用dlopen()调用来打开。
最后,我还听到一些开发人员提到“共享档案”,据我了解,共享档案本身也是静态库,但从未被应用程序直接使用。相反,其他静态库将链接到“共享档案”,以将某些(但不是全部)功能/资源从共享档案中拉到正在构建的静态库中。
预先感谢大家的帮助。
更新资料
在向我提供这些术语的上下文中,必须学习Linux的一组Windows开发人员实际上使用了错误的术语。我试图纠正它们,但是(不正确的)语言规范卡住了。
- 共享库:程序启动时自动链接到程序的库,并且作为独立文件存在。该库在编译时包含在链接列表中(即:
LDOPTS+=-lmylib
对于名为的库文件mylib.so
)。该库必须在编译时以及应用程序启动时存在。 - 静态库:一个在构建时就合并到实际程序本身的库,用于一个(较大)应用程序,其中包含应用程序代码和在构建程序时自动链接到程序中的库代码,而最终的二进制文件则同时包含这两个程序主程序和库本身作为单个独立的二进制文件存在。该库在编译时包含在链接列表中(即:
LDOPTS+=-lmylib
对于名为mylib.a的库文件)。该库必须在编译时存在。 - DLL:本质上与共享库相同,但不是在编译时包含在链接列表中,而是通过
dlopen()
/dlsym()
命令加载该库,因此该库无需在构建时就存在,即可进行程序编译。同样,该库不需要在应用程序启动或编译时出现(必需),因为仅在进行dlopen
/dlsym
调用时才需要。 - 共享存档:本质上与静态库相同,但是使用“导出共享”和“ -fPIC”标志进行编译。该库在编译时包含在链接列表中(即:
LDOPTS+=-lmylibS
对于名为的库文件mylibS.a
)。两者之间的区别是,如果共享库或DLL希望将共享归档文件静态链接到其自己的代码,并且能够使共享库中的函数可用于其他程序,而不仅仅是使用它们,则需要使用此附加标志。 DLL内部。当有人为您提供静态库并且您希望将其重新打包为SO时,这很有用。该库必须在编译时存在。
附加更新
“ DLL
”和“ shared library
” 之间的区别只是我当时工作的公司中的一种(懒惰,不准确的)口语(Windows开发人员被迫转移到Linux开发,并且这个术语陷入了僵局),并遵循上述说明。
另外,在S
“共享档案”的情况下,库名后的尾随“ ”文字只是该公司的惯例,而不是整个行业。
.a
文件,“ a”实际上代表“ archove”,它只是目标文件的存档。现代的链接器应该足够好,不必只包含while库,而只包含需要的归档中的对象文件,甚至可以只使用所引用的对象文件中的代码/数据部分。