我感谢以前曾提出过类似的问题-但是阅读它们并没有一个完全解决我们的问题,因此我想寻求任何见解。
[TL; DR]版本:
是否有可能/容易为VS2005 CRT创建一个shim 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]降低第3方dll期望的VS2005 CRT的效果-即构建类似于VS2005 CRT但实际上使用VS2013 CRT的东西。
5]包装第三方dll(即,构建一个用VS2005编译的dll,其中包含对第三方依赖项的所有调用),并提供正确的内存处理,以便它可与我们其他(使用VS2013 CRT的)dll一起使用
最后是问题:
选项5]可能是最多的工作(但成功的可能性最大)-它基本上是选项1],但在我们的控制之下,因此我们不必等待第三方。
在提交这条路线之前,我想问一下别人是否做了与3]或4]类似的事情,或者我们没有想到的其他解决方案。
选项4](构建CRT的Shimmed版本)似乎是最简单的,因为我认为VS2013 CRT已经完成了许多向后兼容工作-因此,找出细节并在2005年之前只是一个案例版本号到2013版本的调用-在很多情况下,我认为即使签名是相同的,所以也只是一个implib条目。
但是,当我通过Google查看时,找不到任何为CRT版本不兼容问题构建垫片dll的人的示例-因此可能比我想象的要难得多(或严重缺乏我的Google Fu)。
所以以为我只想问问是否有人做过类似的事情/知道为什么这是一个愚蠢的想法?
最佳答案
没有合理的方法可以实现匀场。
问题的关键在于STL的实现已更改,这些都是模板。 DLL几乎可以肯定对VS2005 STL进行了内联和非内联调用。如果将VS2005换成VS2013 CRT,则它们的DLL将混合有内联VS2005和非内联VS2013调用。一场确定的灾难。假设VS2013 CRT甚至具有所需的非内联版本。
也就是说,您可以在代码中提供自己的new
和delete
。这些可以转发到您在运行时通过GetProcAddress
检索的相应VS2005版本。这可能就足够了-没有保证。
关于c++ - 如何避免Windows上多个CRT版本的问题(重新讨论了dll?),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23107131/