我很欣赏以前曾经问过类似的问题 - 但是阅读它们时,没有一个问题可以解决我们的问题,所以我想要提出任何见解。
是否可以/轻松为VS2005 CRT创建一个垫片dll,然后将所有呼叫委托给VS2013 CRT?
是否更容易降级VS2013版本以便它使用VS2005 CRT?
或者这些想法都是疯狂的?
我们的C ++应用程序是使用现代版本的C ++编译器(VS2013,gcc 4.8,取决于目标平台)构建的 - 我们使用的一些依赖项需要现代版本,因为它们使用C ++ 11。
我们的应用程序还使用运行时链接(.dll或.so)来打包各种应用程序组件。
在Windows上使生活变得简单我们使用/ MD(或/ MDd进行调试)编译,即使用多线程版本在dll中使用CRT - 我们构建的任何依赖项都会重新编译为使用相同的CRT。
对所有依赖项(在一个单独的dll中)使用相同的CRT意味着如果内存在一个dll中分配并在另一个dll中释放,我们可以避免出现问题,因为使用了相同的堆。
我们有一个由第三方提供的依赖关系(我不会在这里命名和羞辱他们 - 但你知道你是谁!)作为预编译的dll / so而不是源代码。
这是在Windows上使用VS2005(MSVC8)编译的,并使用MSVC8 crt。
他们之前版本的这种依赖很好。他们对这种依赖的api正确地处理了内存的分配和解除分配,所以即使它在我们的应用程序的其余部分使用不同的CRT版本也没有问题。
不幸的是,他们的新版本(“改进版”!)在他们的API中大量使用了C ++模板 - 这些模板在我们的调用代码中扩展,导致尝试从我们的调用代码中删除在其dll中分配的内存。由于这两个区域使用不同的堆,这是非常有问题的。
要解决此问题,我们可以看到以下可能的解决方案
1]让供应商重写(我们已经要求这个,这是长期解决方案,但不会发生一段时间)
2]让供应商使用VS2013进行重新编译,这样我们就可以获得相同的CRT(显然不会发生 - 请问)。
3]将VS2005 CRT用于我们的所有代码(我们不能简单地使用VS2005来构建我们的代码,因为我们需要C ++ 11支持)
4]重新调整第三方dll期待的VS2005 CRT - 即建立一个看起来像VS2005 CRT但实际上正在使用VS2013 CRT的东西。
5]包装第三方dll - 即构建一个用VS2005编译的dll,其中包含对第三方依赖的所有调用 - 并提供正确的内存处理,以便它可以与我们的其他(VS2013 CRT使用)dll一起使用
选项5]可能是最多的工作(但最有可能成功) - 它基本上是选项1]但在我们的控制之下,所以我们不必等待第三方。
在承诺这条路线之前我曾想过要问看其他人是否做过类似3]或4的事情或其他一些我们没有想过的解决方案。
选项4](构建CRT的匀场版本)似乎可能是最简单的,因为我认为很多后向兼容性工作已经在VS2013 CRT中完成了 - 所以只是查找详细信息和fwd'的情况在2005版本的2013版本调用中 - 在很多情况下,我想甚至签名都是相同的,所以只是一个implib条目。
然而,当我通过谷歌查看时,我找不到任何人为CRT版本不兼容性问题构建填充程序的例子 - 所以可能它比我想象的要困难得多(或者我的谷歌缺乏严重缺乏)。
以为我只想问是否有人做过类似的事情/知道为什么这是一个非常愚蠢的想法?
答案 0 :(得分:2)
没有合理的方法可以实现这种补偿。
交易破坏者是STL实施已经改变,那些是模板。 DLL几乎肯定会混合使用VS2005 STL的内联和非内联调用。如果您将VS2005更换为VS2013 CRT,他们的DLL将混合使用内联VS2005和非内联VS2013调用。一场明确的灾难。这是假设VS2013 CRT甚至需要非内联版本。
也就是说,您可以在代码中提供自己的new
和delete
。这些可以转发到您在运行时通过GetProcAddress
检索的相应VS2005版本。这可能或许足够 - 没有保证。