使用不同版本的C运行时库构建的库进行静态链接,好还是坏?

9
考虑以下情况: 一个应用程序链接到第三方库A。
A是使用MSVC 2008构建的,并且静态链接(即使用/MT选项)到C运行时库v9.0。
该应用程序使用MSVC 2005构建,并且静态链接到A和(使用/MT选项)C运行时库v8.0。
我可以看到这会有问题,例如运行时库版本之间头文件中的类型是否发生了更改。
是否注意保持运行时库头文件在不同版本之间的兼容性?或者应该始终确保所有静态链接库都链接到相同版本的运行时库?
3个回答

14

这应该不是问题。每个库都链接到自己的运行时,并在进程中独立地工作。当库ABI定义不好时,问题就会出现。如果在一个库中分配了任何类型的堆分配对象,在跨库边界传递并在另一个库中“释放”,由于使用了不同的堆管理器来释放堆管理器用于分配它的块,就会出现问题。

任何类型的C运行时定义的结构、对象或实体都不应该在可能使用不同运行时版本的边界上进行传递:例如从一个库获取的FILE*对于链接到不同运行时的不同库没有意义。

只要库API仅使用原始类型,并且不尝试free()传入的指针或传递指向内部malloc()的内存的指针,而期望应用程序(或另一个库)释放(),则应该可以正常工作。

很容易陷入"FUD"的误区,认为如果混合使用C运行时,就会发生“任何事情都可能错”的情况,但您必须记住,库和动态库(.so/.dll/.dylib)通常是使用各种语言开发的:允许使用汇编语言、C、C++、fortran、pascal等语言编写的代码通过有效的CPU高效的二进制接口进行通信。

为什么突然在C链接到C时惊慌失措呢?


3

这个计划非常糟糕,建议避免。可以选择重新编译2005年的库或者编译使用2008年的应用程序。


2
让我有点困惑的是,可能有很多应用程序链接到旧的第三方库(进而链接到旧的CRT)。虽然我同意这似乎很危险,但实践中似乎并不危险。 - Viktor

0

这绝不是一个好主意。您无法控制运行时库所做的假设以及它们如何实现某些类型。这更可能会创建一种混乱而不是解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接