我最近在学习CMake,从中了解了共享库和模块库之间区别的概念。
一些最近的相关学习材料(不是全部):
https://cmake.org/cmake/help/v3.0/prop_tgt/TYPE.html
https://cmake.org/cmake/help/latest/command/add_library.html
https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
我在介绍 CMake 后才意识到这种区别。
在此之前,我只知道共享库和静态库的区别。我认为所有
.so
文件都是共享库,但现在看来 .so
文件可能是共享库或模块库(?)而且我的印象是用户可以选择 链接 .so
文件或加载它(使用
dlopen()
或类似功能)。但现在,根据我正在进行的学习,我形成这样的印象:用户需要知道他的
.so
是共享库还是模块库,对于前者,必须仅链接与它,对于后者必须只加载它。 对我来说,一个困惑点是,似乎一个
can 要么链接到 .so
文件,要么加载它,从某种意义上说,链接到
gcc
文件的
g++
/
.so
调用将返回 0(假设符号已正确解析等),同时在同一个
dlopen()
文件上运行
.so
也会成功。我的问题是:
谁能解释一下共享库和模块库之间的区别和起源吗?
鉴于人们似乎可以成功地链接到 .so
文件或加载它,那么何时以及为什么它们之间的选择很重要? (从实现简单 hello-world 函数的示例
.so
文件中,我并不清楚选择的重要性)如果用户希望知道所需的
.so
文件是共享库还是模块库(以及是否要链接它或加载它),那么通常如何传达该信息?使用
libuv
作为示例,因为我最近一直在使用它,所以我在其README.md 或 用户指南中没有找到有关此主题的冗长内容。 CMake 是这种区别的起源吗?搜索“共享库与模块库”会导致大部分与 CMake 相关的页面。我在
有关共享库的 Linux 文档项目页面上不认识/注册对此区别的任何评论。
.so
文件而不是
.dll
文件)上,但如果答案与 Windows、*nix(和其他系统)之间的差异有关,请让我知道是否可以相应地更好地表达问题。
这个相关,但我认为这个问题是不同的,因为我试图了解共享库和静态库之间区别背后的原理/历史,而不是仅仅了解 CMake有助于区分(或者使这种区别对于像我这样的人来说更加明显,他们的印象是所有 .so
文件都是共享库,并且用户可以任意选择是否链接到它或加载它)。
dlopen
共享库。但是,在 Windows 上存在差异。 Windows 上的共享库通常由两个文件组成:运行使用共享库的程序时加载的 .dll 文件,以及链接器在创建可执行文件时使用的 .lib 文件。构建链接到共享库的程序根本不需要 .dll,同样,您可以在不存在 .lib 文件的情况下运行这样的程序。
因为 MODULES 需要手动加载而不是链接,所以 MODULE 库不会创建 .lib 文件,因此在 Windows 上您实际上无法链接到 MODULE 库。