一般问题:
对于非托管 C++,内部代码共享哪个更好?
- 通过共享实际源代码来重用代码?或者
- 通过共享库/动态库(+所有头文件)重用代码
不管它是什么:你减少重复代码(复制粘贴综合症)、代码膨胀的策略是什么?
具体例子:
以下是我们在我的组织中共享代码的方式:
我们通过共享实际源代码来重用代码。
我们使用 VS2008 在 Windows 上进行开发,尽管我们的项目实际上需要跨平台。我们有许多项目(.vcproj)提交到存储库;有些可能有自己的存储库,有些可能是存储库的一部分。对于每个可交付的解决方案 (.sln)(例如,我们交付给客户的东西),它将 svn:externals 从存储库中获取所有必要的项目 (.vcproj) 以组装“最终”产品。
这很好用,但我很担心最终每个解决方案的代码大小会变得非常大(现在我们的总代码大小约为 75K SLOC)。
另外需要注意的一件事是我们防止所有传递依赖。也就是说,每个不是实际解决方案 (.sln) 的项目 (.vcproj) 都不允许 svn:externals 任何其他项目,即使它依赖于它。这是因为您可能有 2 个项目(.vcproj)可能依赖于同一个库(即 Boost)或项目(.vcproj),因此当您将 svn:externals 两个项目合并为一个解决方案时,svn:externals 将执行两次. 因此,我们仔细记录每个项目的所有依赖项,并由创建解决方案 (.sln) 的人来确保所有依赖项(包括传递性)都是 svn:externals 作为解决方案的一部分。
如果我们通过使用 .lib 、 .dll来重用代码,这显然会减少每个解决方案的代码大小,并在适用的情况下消除上面提到的传递依赖(例外情况是,例如,使用dll 像 Intel TBB 和默认的 Qt)
附录:(如果您愿意,请阅读)
GUI 博士可能最好地总结了共享源代码的另一个动机:
最重要的是,C++ 使简单的不是创建可重用的二进制组件。相反,C++ 使得重用源代码变得相对容易。请注意,大多数主要的 C++ 库都是以源代码形式提供的,而不是编译形式。为了从对象正确继承,经常需要查看该源代码——当您重用它时,依赖原始库的实现细节太容易(而且通常是必要的)。好像这还不够糟糕,修改原始源代码并进行库的私有构建通常很诱人(或有必要)。(有多少 MFC 的私有版本?世界永远不会知道......)
也许这就是为什么当您查看诸如 Intel Math Kernel 库之类的库时,它们的“lib”文件夹中的每个 Visual Studio 版本都有“vc7”、“vc8”、“vc9”。可怕的东西。
或者这个断言怎么样:
C++ 在插件方面是出了名的不适应。C++ 是极其特定于平台和编译器的。C++ 标准没有指定应用程序二进制接口 (ABI),这意味着来自不同编译器甚至同一编译器的不同版本的 C++ 库是不兼容的。除此之外,C++ 没有动态加载的概念,每个平台都提供自己的解决方案(与其他平台不兼容),您就可以了解情况。
您对上述说法有何看法?像 Java 或 .NET 这样的东西会面临这些问题吗?例如,如果我从 Netbeans 生成一个 JAR 文件,如果我将它导入 IntelliJ,只要我确保两者都具有兼容的 JRE/JDK,它会起作用吗?