我对VS2010和VS2012之间编译库的二进制兼容性感到困惑。我想迁移到VS2012,但是许多仅用于闭源的二进制SDK仅适用于VS2010,例如用于连接硬件设备的SDK。
传统上,据我所知,Visual Studio对编译器版本非常挑剔,而在VS2010中,您无法链接到已为VS2008编译的库。
我现在感到困惑的原因是,我正在迁移到VS2012,我尝试了一些项目,而且我最大的惊喜是,他们中的许多人都可以毫无问题地使用跨版本。 / p>
注意:我不是在谈论v100模式,据我所知,这只是VS2010编译引擎上的VS2012 GUI。
我说的是在VS2012中打开VS2010解决方案,点击更新,看看会发生什么。
当链接到一些更大的库,比如boost时,编译不起作用,因为检查编译器版本并且它们引发错误并中止编译。其他一些库只是在缺少功能时中止。这就是我所期待的行为。
另一方面,许多图书馆工作正常,没有错误或其他警告。
怎么可能? VS2012是否以特殊方式制作,以保持与VS2010库的二进制兼容性?它是否依赖于动态链接和静态链接?
最重要的问题:即使在编译时没有出现错误,我可以相信编译器在将VS2012项目链接到VS2010编译库时不会有任何错误吗?
答案 0 :(得分:3)
“许多图书馆工作正常。怎么可能?“
1)lib被编译为使用静态RTL,因此代码不会引入第二个发生冲突的RTL DLL。
2)代码只调用完全在头文件中的函数(并使用结构等) 所以不会导致链接器错误,或者 调用仍然存在于新RTL中的函数,因此不会导致链接器错误,
3)不会对具有更改布局或含义的结构调用任何内容,因此不会崩溃。
#3是值得担心的。您可以使用导入来查看它使用的内容并制作完整的列表,但是没有文档或保证哪些是兼容的。仅仅因为它似乎运行并不意味着它没有潜在的错误。
还有可能
4)编写了驱动程序SDK或其他代码相当低的代码,以避免完全使用标准库调用。
(也就是我认为不是你的情况)DLL可以被隔离并拥有自己的RTL,而不是在不同的机制之间来回传递内容(如内存分配和释放)。进程内COM服务器以这种方式工作。如果你仔细考虑你传递和返回的内容以及你对指针这样的事情做了什么,那么DLL 可以这样做。例如,Crypto ++使用封闭程序中的内存例程进行初始化,并且不会从编译它的RTL版本中公开malloc的内存。