混合使用不同编译器版本构建的二进制文件

时间:2013-10-14 12:16:08

标签: c++ visual-c++ dll static-libraries

我想知道,调用代码放在一个.dll中,可能是用不同的工具链构建的吗?并且正在使用旧的编译器构建.lib文件来构建更新的代码吗?

我知道,第二个不是更好,但我想知道,这是不可能的。

我的案例看起来很像:

我使用a.exe文件使用VC7.1构建了b.lib文件,该文件也是使用VC7.1构建的。 a.exe调用c.dll的代码,该代码也是使用b.dll构建的。现在我想写一个新的c.dll,但用VC9编译它。 (我想这样做,因为我需要一些不支持使用VC7.1构建它们的库。) - 我的c.dll也需要b.lib,但我仍有源代码,因此我可以重新编译它。

那么,是否有可能使其有效?如果没有,你能提供一个简短的解释,究竟什么不允许这个?

1 个答案:

答案 0 :(得分:9)

这并非完全不可能。主要问题是你不可避免地会得到运行时库的两个不同副本。复制每个都保持自己的状态并使用自己的内存分配器。 DLL接口必须经过精心设计,以避免可能导致的错误。

硬规则是你永远不能从DLL中的代码中抛出异常并在EXE中捕获它。并且您无法从DLL代码返回标准C ++库对象(如std :: string),它们具有不同的实现,并且EXE无法正确销毁该对象,因为它使用不同的分配器。更一般的规则是,DLL永远不会返回指向需要由调用者释放的对象的指针。 CRT状态可能会导致细微的问题,例如errno没有返回正确的错误代码并且区域设置错误。总而言之,很多痛苦很难诊断,甚至难以修复。

COM编程模型是一个安全的例子。它从不暴露实现,只暴露纯粹的抽象接口。没有例外,只有错误代码。对象由工厂分配并计算引用。在绝对必要的地方,它使用一个公共堆来分配CoTaskMemAlloc()。不是一种流行的编程模型,而是它需要的东西。