在c++中创建类库时,可以在动态(.dll, .so)和静态(.dll, .so)之间进行选择。Lib, .a)库。它们之间的区别是什么?什么时候使用哪个比较合适?
当前回答
除了静态库与动态库的技术影响(静态文件将所有内容捆绑在一个大的二进制文件中,而动态库允许在几个不同的可执行文件之间共享代码)之外,还有法律影响。
例如,如果您正在使用LGPL许可的代码,并且静态地链接到一个LGPL库(从而创建了一个大的二进制文件),那么您的代码将自动成为开源(自由)LGPL代码。如果您链接到一个共享对象,那么您只需要LGPL对LGPL库本身所做的改进/错误修复。
例如,如果你决定如何编译你的移动应用程序,这就成为一个更重要的问题(在Android中你可以选择静态和动态,在iOS中你不能-它总是静态的)。
其他回答
如果您的库将在几个可执行文件之间共享,那么将其动态化以减少可执行文件的大小通常是有意义的。否则,一定要让它是静态的。
使用dll有几个缺点。装载和卸载它有额外的开销。还有一个额外的依赖关系。如果您更改dll使其与执行表不兼容,则它们将停止工作。另一方面,如果您更改了静态库,则使用旧版本编译的可执行文件将不会受到影响。
除了其他人提到的所有要点,我在特定的用例中使用静态库:
不允许我的终端用户访问一些通用库 我在我的代码中开发的。
换句话说,假设我的产品中有两个库,A和B。A使用B服务并依赖于它。但是B是一个通用库,包括许多可以单独使用的有用服务。为了避免我的终端用户直接从B中受益(他们应该为B的许可证付费!),我通常将B编译为一个静态库,并将其直接放在a中。因此,B服务对a来说是完全私有的,最终用户不能使用。
除了静态库与动态库的技术影响(静态文件将所有内容捆绑在一个大的二进制文件中,而动态库允许在几个不同的可执行文件之间共享代码)之外,还有法律影响。
例如,如果您正在使用LGPL许可的代码,并且静态地链接到一个LGPL库(从而创建了一个大的二进制文件),那么您的代码将自动成为开源(自由)LGPL代码。如果您链接到一个共享对象,那么您只需要LGPL对LGPL库本身所做的改进/错误修复。
例如,如果你决定如何编译你的移动应用程序,这就成为一个更重要的问题(在Android中你可以选择静态和动态,在iOS中你不能-它总是静态的)。
Ulrich Drepper关于“如何编写共享库”的论文也是一个很好的资源,详细介绍了如何最好地利用共享库,或者他所说的“动态共享对象”(DSOs)。本文主要讨论ELF二进制格式的共享库,但有些讨论也适用于Windows dll。
静态库被编译到客户机中。在编译时使用.lib,库的内容成为消费可执行文件的一部分。
动态库在运行时加载,而不是编译到客户端可执行文件中。动态库更加灵活,因为多个客户端可执行文件可以加载一个DLL并利用它的功能。这也将客户端代码的总体大小和可维护性保持在最小。