【发布时间】:2012-04-12 17:54:47
【问题描述】:
我在使用 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?机器上最新的,还是更“并排”的机制。
【问题讨论】:
-
据我所知,在Linux中重建所有项目和依赖项通常不是问题,因为代码经常可用。
-
glibc(C 库的 GNU 实现,涵盖 ISO C + POSIX + 一些扩展)使用版本化符号来处理版本之间的兼容性。几乎所有其他库作者都不太关心版本之间的这种兼容性,因为无论如何,大多数 Linux 软件都是作为源代码分发的,并且可以随意重新编译(通过发行版,甚至由最终用户)。
-
从技术上讲,由于上述符号版本,不同代码部分调用不同 samefunc@@version 的问题也可能在 Linux 上发生。然而,与 msvcrt 不同的是,glibc 迄今为止仍然只有一个 malloc 符号 (malloc@@GLIBC_2.2.5)。我也不明白为什么它需要更多,毕竟自 ANSI C 以来,malloc 的 ABI 没有改变,而且不太可能很快改变。