从不同版本的Visual Studio混合库时的运行时问题

时间:2009-12-22 17:15:08

标签: windows visual-studio visual-c++ linker

运行我使用两个不同版本的Visual Studio构建的项目时遇到意外的访问错误。我的一般配置如下:

  • LibA是一个静态库,静态运行时链接,msvc 8.0
  • LibB是一个静态库,静态运行时链接,msvc 9.0
  • 我的集成目标项目是一个msvc 9.0 COM dll,它静态链接上面的库

此项目构建,但在运行时因某些STL代码中的访问冲突而崩溃。堆栈似乎表明我在调用流插入操作符期间通过了两个版本(8和9)的头文件。我意识到这是一个问题。

不知何故,这个电话:

ost << std::dec << port_; //(originating from an object in LibA)

...通过以下堆栈跟踪下降:

std::basic_ostream::operator<<(...) (ostream:283, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::put(...) (xlocnum:888, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::do_put(...) (xlocnum:1158, msvc 9.0 version!! !@#$!%! <-- not expected, since LibA was built with msvc 8.0)
std::ios_base::flags() (xiosbase:374, msvc 9.0 version <-- follows from above)

访问冲突发生在std :: ios_base :: flags()中。我怀疑这是由于调用堆栈中的实现混合(虽然我不确定)。

我的问题是。

1。)这种访问违规的可能原因是msvc头实现的混合吗?
2.)有没有办法防止这些实现混合?
3.)是否有更好的方法来配置这三个项目进行集成(假设从msvc 8.0移动LibA是不可取的)?

我了解this questionthis one中提出的想法。在这里,我对这个具体问题最感兴趣,如果有办法可以避免它。

任何见解都将不胜感激。

2 个答案:

答案 0 :(得分:7)

您不能在同一个项目中使用不同的STL实现。这意味着甚至来自同一编译器的不同版本。如果您的LibA具有接受std :: vector作为参数的函数,则只允许从构建LibA的STL传递向量对象。这就是为什么许多C ++库只公开C API。

您可以更改API,也可以使用相同的编译器重建所有项目。

你正在做一些你不应该做的事情。你处于未定义行为的世界。尝试调试此特定崩溃是没有意义的。即使你设法使这条线工作,你也会在其他地方遇到新的崩溃。

答案 1 :(得分:1)

无法保证主要版本的MSVC之间的库二进制兼容性。 STL代码主要是模板代码,可以扩展到您的代码中。因此,您的静态库可能在其中包含不兼容的STL代码块。

通常,这应该不是问题,除非该STL代码是库的接口的一部分。例如,如果您将迭代器或对某个库的向量的引用传递给另一个库,则会遇到麻烦。

最好的解决方案是使用相同版本的编译器构建所有内容。如果您不能这样做(例如,如果其中一个库来自第三方),您可能会被卡住。