2013-10-14 58 views
3

我想知道,是否调用放置在.dll中的代码,使用不同的工具链构建该代码?并且正在使用一个.lib文件与一个较旧的编译器一起构建一个更新的代码。使用不同编译器的版本构建的混合二进制文件

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

正是我的情况是这样的:

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

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

+0

一个大问题是你会得到一个不同的CRT,这意味着你得到一个不同的堆。这会导致解除分配问题。 – drescherjm

回答

8

这并非完全不可能。主要的问题是,你将不可避免地以两个不同的运行时库副本结尾。每个副本保留自己的状态并使用自己的内存分配器。必须仔细设计DLL接口以避免可能导致的可能的故障。

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

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

相关问题