VS2010和VS2012之间的二进制C++库兼容性问题?

4
我对VS2010和VS2012编译库的二进制兼容性感到困惑。我想迁移到VS2012,但许多闭源的仅为VS2010提供SDK,例如用于与硬件设备交互的SDK。
据我所知,传统上,Visual Studio对编译器版本非常挑剔,在VS2010中,您不能链接到已为VS2008编译的库。
我现在感到困惑的原因是,我正在迁移到VS2012的过程中,并尝试了一些项目,令我最惊讶的是,其中许多跨版本工作都没有问题。
注意:我不是在谈论v100模式,据我所知,它只是VS2010编译引擎上的VS2012 GUI。
我说的是在VS2012中打开VS2010解决方案,点击更新,看看会发生什么。
当链接到一些更大的库,如boost时,编译不起作用,因为有编译器版本检查,它们会引发错误并中止编译。一些其他库只是因缺少函数而中止。这是我预期的行为。
另一方面,许多库可以正常工作,没有错误或额外的警告。
这是怎么可能的?VS2012是否以特殊方式制作,以保持与VS2010库的二进制兼容性?是否取决于动态与静态链接?
最重要的问题是:即使在编译时没有引发错误,我能相信编译器在将VS2012项目链接到VS2010编译库时不会出现任何错误吗?

1
许多跨版本的程序通常没有问题。只要你知道这个限制,它们很可能会在大部分情况下正常运作。然而,更有可能的是它们只是碰巧99%的时间能够对齐,并且看起来似乎工作正常。传递一个 std::deque 可能不会显示编译器错误,但很可能会导致崩溃。 - Mooing Duck
VS2012环境确实会寻找您的各种构建工具链,并允许您将它们用作v110(或CTP)的替代方案。它不是在某个神奇的替代宇宙中运行的VS2012。它只是使用您告诉它用于构建实现的任何东西。这也是如何随意使用(或不使用)CTP的。 - WhozCraig
2
标准库在不同版本之间没有二进制兼容性。有太多的内联和数据结构变化。另请参见如何在C++中构建与运行时版本无关的DLL? - Cory Nelson
1个回答

3
“很多库都能正常工作,这是怎么做到的呢?”
1)该库已编译为使用静态RTL,因此代码不会拉取第二个与之冲突的RTL DLL。
2)代码仅调用头文件中完全包含的函数(并使用结构等),因此不会导致链接器错误,或者调用仍然存在于新RTL中的函数,因此不会导致链接器错误。
3)不调用任何具有更改布局或含义的结构的内容,因此不会崩溃。
#3是需要担心的。您可以使用导入来查看它使用了哪些部分,并制作完整列表,但是没有文档或保证哪些是兼容的。仅因为它似乎在运行,就不意味着它没有潜在的错误。
还有可能是:
4)驱动程序SDK或其他相当低级别的代码被编写以完全避免使用标准库调用。
此外(我认为不是您的情况),DLL可以被隔离并具有自己的RTL,并且不会在不同的环境之间传递东西(如内存分配和释放)。In-proc COM服务器以此方式工作。 DLL通常可以这样做,如果您小心处理要传递和返回的内容以及指针之类的内容,不过Crypto ++就是这样初始化的,它使用封装程序的内存例程,并不会从其编译版本中暴露malloc'ed内存。

1
是的,兼容性问题不在于工具链,而在于常见数据类型的内存布局以及内联函数中嵌入的假设。 - Ben Voigt

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