我在微软的CRT上遇到了很多概念问题。对于任何项目,您必须编译所有必需的库以链接相同版本的CRT。
第一个问题是您的项目静态链接到CRT(/ MT)。然后所有依赖库也必须静态链接自己的CRT。因此每个库都有自己的版本 - 例如 - malloc()。如果您去年在系统A上编译了其中一个库,则该CRT版本可能与您在另一个具有Service Pack 3+的系统B上使用的版本不同。因此,如果你释放库分配的对象,你可能会遇到问题。
所以似乎动态链接CRT是要走的路(/ MD)。使用dll,所有库都将获得系统上CRT的当前实现。除了微软的并排机制,这不是发生的事情。相反,您将获得在您编译的库上标记的CRT版本,并且该DLL版本将提供给该库。因此,我之前描述的完全相同的问题可能发生。您在一年前针对一个CRT在系统A上编译库。一年后,有一个升级的新版本。您的主程序使用一个版本的CRT获取DLL,该库获取另一个版本的CRT的DLL,可能会出现同样的问题。
那你做什么?我意识到跨库内存分配是不受欢迎的。但是您可以忽略malloc示例并提出另一个示例。您是否让每个开发人员重新编译其计算机上的每个依赖库以确保一切都使用相同的CRT?然后,对于发布,您再次重新编译每个库?
这如何在Linux上运行?这是我的主要兴趣。是否有GCC提供的CRT或Linux系统本身附带CRT库?我从来没有见过在Makefils中明确链接的CRT。
在Linux上,动态库链接的CRT是什么?机器上最新的一个,或者它是更“并排”的机制。
答案 0 :(得分:2)
在Linux方面,我认为标准库有两个基本部分存在争议:我们有C-runtime部分,它应该永远与ABI兼容。实际上,无论哪个版本链接在最终链接时都应该没问题,如果它是兼容性所需的旧版本,您可以使用二进制文件重新分发任何所需的共享库。通常,这些库只是并排放在* NIX系统上。
其次,你有C ++库。这些几乎可以保证不会以任何方式与ABI兼容,因此必须重建最终二进制文件的每个组件,而不是相同版本的C ++库。不幸的是,没有办法绕过它,否则你可能会遇到各种各样的错配。这就是为什么许多开源库甚至不需要使用预制的库二进制文件:每个人都需要构建自己的副本,以确保它能正确链接到最终的应用程序代码。