6

我想知道,调用代码是否可以放置在使用不同工具链构建的 .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,我仍然有它的源代码,因此我可以重新编译它。

那么,有没有可能让它发挥作用?如果没有,您能否提供一个简短的解释,究竟是什么不允许这样做?

4

1 回答 1

11

这并非完全不可能。主要问题是您将不可避免地得到两个不同的运行时库副本。每个都保持自己的状态并使用自己的内存分配器的副本。必须仔细设计 DLL 接口以避免可能导致的意外事故。

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

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

于 2013-10-14T12:56:00.067 回答