3

我在使用 Microsoft 的 CRT 时遇到了很多概念问题。对于任何项目,您必须编译所有必需的库以链接到相同版本的 CRT。

第一个问题是当您的项目静态链接到 CRT (/MT) 时。然后所有依赖库也必须静态链接自己的 CRT。所以每个库都有自己的版本——例如——malloc()。如果您去年在系统 A 上编译了其中一个库,则该 CRT 版本可能与您当前在另一个带有 Service Pack 3+ 的系统 B 上使用的版本不同。因此,如果您要释放由库分配的对象,您可能会遇到问题。

所以看起来动态链接的 CRT 是要走的路(/MD)。使用 dll,所有库都将获得系统上 CRT 的当前实现。除了 Microsoft 的 Side by Side 机制之外,情况并非如此。相反,您会获得在您编译的库上标记的 CRT 版本,并且该版本的 DLL 将提供给该库。因此,可能会发生与我之前描述的完全相同的问题。您在一年前针对一个 CRT 在系统 A 上编译了一个库。一年后有一个升级的新版本。您的主程序使用一个版本的 CRT 获取 DLL,该库使用另一个版本的 CRT 获取 DLL,可能会出现同样的问题。

所以你会怎么做?我意识到跨库内存分配是不受欢迎的。但是您可以忽略 malloc 示例并提出另一个示例。您是否让每个开发人员在他们的机器上重新编译每个依赖库以确保所有内容都使用相同的 CRT?然后对于发布你重新编译每个库?

这在 Linux 上是如何工作的?这是我的主要兴趣。是否有 GCC 提供的 CRT 或 Linux 系统本身带有 CRT 库?我从未在 Makefils 中看到过明确链接的 CRT。

在 Linux 上,动态库链接到什么 CRT?机器上最新的一个,还是更“并排”的机制。

4

1 回答 1

2

在 Linux 方面,我认为标准库的两个基本部分存在问题: 我们有 C 运行时部分,它应该永远与 ABI 兼容。实际上,最终链接时的任何版本链接都应该没问题,如果它是兼容性所需的旧版本,您可以使用二进制文件重新分发任何需要的共享库。通常,这些库只是在 *NIX 系统上并排放置。

其次,你有 C++ 库。这些几乎可以保证不以任何方式与 ABI 兼容,因此您必须针对相同版本的 C++ 库重新构建最终二进制文件的每个组件。不幸的是,没有办法解决它,否则你可能会遇到各种不匹配。这就是为什么许多开源库甚至不使用预制库二进制文件的原因:每个人都需要构建自己的副本以确保它能够正确链接到他们的最终应用程序代码中。

于 2012-04-12T19:09:13.437 回答