但我认为这会增加负担,因为我们编写的代码既不需要在同一台机器上的应用程序之间共享,也不需要动态加载或卸载,我们可以简单地链接一个单体可执行应用程序。
此外,用C函数接口包装C++类会使它变得更丑陋。
我还认为,单个文件的应用程序在客户现场进行远程升级会更容易。
当没有必要在应用程序之间共享二进制代码,也没有动态代码加载时,是否应该使用动态库?
即使没有任何重复使用,也可以提高重复使用率吗?听起来不像是一个有力的论点。
代码的模块化和可测试性不需要依赖于最终部署的单元。我期望链接是一个晚期决策。
如果你真的只有一个可交付成果,并且从未预计对其进行任何更改,那么分阶段交付似乎过于繁琐和不必要的复杂性。
简短回答:不需要。
更详细的回答:动态库与单体应用程序相比,对测试、模块化或重用并没有额外的好处。我唯一能想到的好处是可能会迫使一个团队在没有自律的情况下创建API。
库(无论是静态还是动态)本身并没有什么神奇之处。如果您拥有构建应用程序所需的所有代码和各种库,则可以轻松地将它们全部编译为单个可执行文件。
总的来说,我们发现,除非有强烈的需求(多个应用程序中的库,需要更新多个应用程序而无需重新编译,使用户能够向应用程序添加功能),否则处理动态库的成本是不值得的。
如果他认为将你的代码拆分为共享库会提高代码的模块化、可测试性和重用性,那么我想这意味着他认为你的代码存在一些问题,并且强制执行“共享库”架构将改正它。
您的代码必须具有不希望发生的相互依赖关系,若在“库代码”和“使用库代码的代码”之间进行更清晰的分离,则这种情况将不会发生。
现在,这也可以通过静态库实现。
您的代码可能需要更好地进行测试,例如为每个单独的共享库构建单元测试,在每次编译时自动化执行。
现在,这也可以通过静态库实现。
您的同事想要重用某些未公开的代码,因为它隐藏在您的单块应用程序的源代码中。
第1点和第2点仍然可以通过静态库实现。第3点将使共享库成为必需。
现在,如果您有多层库链接(我正在思考将两个已经编译链接其他库的静态库链接在一起),这可能会很复杂。在Windows上,这会导致链接错误,因为某些函数(通常是C/C++运行时函数,当静态链接时)被引用多次,编译器无法选择要调用的函数。我不知道Linux上如何工作,但我想这也可能发生。
您自己的论点有些有偏见:
与编译/链接静态库相比,编译/链接共享库的负担不存在。因此,这个论点没有价值。
在极少数情况下,动态加载/卸载共享库可能是一个问题。在正常情况下,操作系统会在需要时加载/卸载库,而且,您的性能问题在其他地方。
至于将C ++代码使用C函数接口,我不能理解:您已经使用C ++接口将静态库链接在一起。链接共享库没有任何区别。
如果您需要使用不同的编译器来生成应用程序中的每个库,那么您将遇到问题,但这不是问题,因为您已经将库静态链接在一起。
您是正确的。
在Windows上,差异微不足道,但这就是DLL地狱的问题,如果将版本添加到库名称中或使用Windows XP,则问题消失。
在Linux上,除了上述的Windows问题之外,你还需要知道默认情况下共享库需要在一些系统默认目录中才能使用,所以你需要在安装时将它们复制到那里(这可能会很麻烦...)或更改一些默认环境设置(这也可能很麻烦...)共享库带来了一些麻烦,但我认为在这里使用共享库是正确的选择。我认为在大多数情况下,您应该能够使应用程序的某些部分模块化并可重用于业务的其他地方。此外,根据这个庞大的可执行文件的大小,只需上传一组更新的库可能会更容易,而不是一个大文件。
在我看来,通常情况下,库可以导致更好的代码、更易于测试的代码,并且允许未来的项目以更高效的方式创建,因为您不必重新发明轮子。
简而言之,我同意您的同事的观点。
进行简单的成本/效益分析 - 您真的需要模块化、可测试性和重用性吗?您有时间花费重构代码来获得这些功能吗?最重要的是,如果您确实进行了重构,您获得的好处是否能够证明执行重构所花费的时间是值得的?
除非您现在存在测试问题,否则我建议将应用程序保留为原样。模块化很棒,但Linux有自己的“DLL地狱”版本(请参见ldconfig
),而且您已经表明重用不是必需品。
如果你提出问题,而答案并不明显,那么就留在原地。如果你还没有达到构建单体应用程序需要太长时间或者对于你的团队来说太麻烦的程度,那么没有必要转向库。如果你想要的话,可以构建一个测试框架,它可以在应用程序的文件上工作,或者你可以简单地创建另一个项目,使用相同的文件,但附加一个测试API,并构建一个库。
为了运输目的,如果你想要构建库并且发货一个大型可执行文件,你总是可以静态链接到它们。
如果模块化有助于开发,即你总是与其他开发人员在文件修改方面发生冲突,那么库可能会有所帮助,但这也不是保证。无论如何,使用良好的面向对象的代码设计都会有所帮助。
没有理由包装任何函数与C可调用接口必要创建一个库,除非你希望它可以从C中调用。
结论: