在我公司,我们最近从VC9切换到VC10。
我们迁移了我们的项目但是,负责人告诉我们,我们必须在生产机器上保留一些用VC9编译的基本常见DLL一段时间。
这些DLL使用自定义结构,其中一些包含std::vector
,std::map
等。现在,我注意到标准容器的尺寸发生了变化:一些变大了,一些变小了。结果,我们的自定义结构的大小也发生了变化。
为了解决尺寸变化引起的问题,我的一位同事想到人为地增加我们结构的尺寸,以便能够补偿未来的构件尺寸变化,以便结构保持相同的尺寸,无论我们使用何种运行时间,防止函数调用中的堆栈损坏。
就个人而言,我觉得这个“解决方案”很糟糕,因为虽然尺寸很重要,但结构的布局也很重要。对我来说,增加所有结构的内存占用以修复组织问题似乎是错误的。
为了缩短它,我的问题是:在函数原型中使用非C类型时,是否可以同时使用两个不同的运行时(使用所描述的技巧或任何其他技巧)?对于类似的情况你有任何好/坏的经历吗?
答案 0 :(得分:9)
STL从未保证不同主要版本之间的二进制兼容性。因此,如果在接口上有DLL的STL类,则应该为DLL的客户端和DLL本身使用相同的编译器和相同的CRT风格。
如果你想构建可以安全地与不同编译器版本一起使用的DLL,你有一些选择,比如:
答案 1 :(得分:1)
您必须确保需要使用这些旧库的任何内容与它们相关联,并根据这些库的那个版本附带的头文件进行编译。没有其他办法可以做到这一点,因为C ++必须能够看到头文件才能知道如何处理任何数据结构。
我从你的问题中得到的印象是,你将链接到一些库,这些库依次编译并链接到VC9运行时,在这种情况下,很可能将其余代码与VC10链接,只是只要库不在其接口中公开任何VC9库类型。我说'很可能',这是一个充满陷阱和陷阱的区域,通常我会说你应该尽可能使用相同的运行时。你需要的最后一件事是编译器对你正在谈论的std :: vector版本感到困惑(你可以保证程序员也会感到困惑,即使你能说服编译器和链接器搞清楚)
它更糟糕,但更容易,只需坚持使用旧的运行时,直到任何目标机器上不再需要它为止。
答案 2 :(得分:1)
我之前实际上已经这样做了,以类似的方式填充结构。是的,你可以使用两个不同的运行时间,只要ABI是相同的,它应该可以正常工作:当结构开始改变大小时,你会碰壁,并且移动C ++(ABI遍布各处) DLL边界真的非常混乱。特别是考虑到VC10在预期C ++ 11方面有很多变化。我使用的是C所关注的DLL,完全是为了保证它在二进制兼容性方面给我的。
我很难提供一个特定的案例,其中的东西真的会吃掉它,但是让我以这种方式把它给你:这是你不会想到的错误,这是一个真正的黄蜂巢。