【发布时间】:2009-10-26 13:00:28
【问题描述】:
我们使用由 VC6 编译器构建的内部库(由其他团队开发)。该库主要包含 C 风格的 API。我们计划迁移到 Visual Studio 9 编译器。我应该要求使用 VC9 编译器构建库吗?
一个更通用的问题,使用两个不同版本的 Visual Studio 编译器构建的 DLL 在哪些方面(可能是名称修改、优化等)不同?
【问题讨论】:
标签: c++ c visual-c++-6 visual-c++-2008
我们使用由 VC6 编译器构建的内部库(由其他团队开发)。该库主要包含 C 风格的 API。我们计划迁移到 Visual Studio 9 编译器。我应该要求使用 VC9 编译器构建库吗?
一个更通用的问题,使用两个不同版本的 Visual Studio 编译器构建的 DLL 在哪些方面(可能是名称修改、优化等)不同?
【问题讨论】:
标签: c++ c visual-c++-6 visual-c++-2008
冲突通常发生在 C 运行时库中。主要思想是应该在分配内存的模块中释放内存。然后可以安全地使用使用不同版本的编译器构建的库。另一个问题是结构体的打包,但如果你只使用 Visual C++ 编译器,这没有区别。
Name mangling 在 Visual C++ 中因版本而异,但它仅适用于 C++ 库。如果您使用 C 样式导出(例如,如果您有 DEF 文件),则无需担心。
This 的问题与您的问题不完全相同,但可能会有所帮助。
【讨论】:
AFAIK,Visual C++ 名称修饰在各个版本之间一直保持稳定。
主要问题是使用一个版本编译的代码必须与该版本的 CRTL 链接,并且将来自多个版本的代码混合到同一个 DLL 或 EXE 中是行不通的,因为这样两个目标代码都需要不同的 RTL 例程。
另一方面,如果您链接包含不同库的单独 DLL,它应该可以工作。毕竟,这就是 DLL 的全部意义所在。
在这种情况下,我建议仅使用 extern "C" API 并(如果这是 32 位代码)明确指定调用约定(__stdcall__ 或 WINAPI 或 _cdecl ...)
此外,当您的应用程序有多个 CRTL 副本时,还有一个微妙的问题:您有多个堆!如果一个对象被分配在一个堆上并释放到另一个堆上,那么这个堆就会立即损坏并且你会崩溃。
总而言之,如果你能让他们用你的编译器重新编译,那是最简单的事情。
【讨论】: