我在运行使用两个不同版本的Visual Studio构build的项目时遇到了意外的访问错误。 我的一般configuration如下:
该项目构build,但在运行时崩溃在一些STL代码访问冲突。 堆栈似乎表明,我已经通过头两个版本(8和9)在调用stream插入运算符。 我意识到这是一个问题。
不知何故,这个电话:
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()中。 我怀疑这是由于调用堆栈中的实现混合(尽pipe我不确定)。
我的问题是。
1.)这个访问冲突的可能原因是混合了msvc头实现吗?
2.)有没有办法阻止这些实现混合?
3.)有没有更好的方式来configuration这三个项目进行整合(假设从msvc 8.0移动LibA是不可取的)?
我知道在这个问题和这个 问题上提出的想法。 在这里我最感兴趣的是这个具体的问题,如果有什么方法可以避免的话。
任何见解,将不胜感激。
您不能在同一个项目中使用不同的STL实现。 这意味着甚至与同一个编译器不同的版本。 如果你的LibA有一个接受std :: vector作为参数的函数,你只允许从构建LibA的STL传递vector对象。 这就是为什么许多C ++库只公开C API的原因。
要么更改您的API,要么使用相同的编译器重建所有项目。
你正在做一些你不应该做的事情。 你处于未定义行为的世界。 试图调试这个特定的崩溃没有意义。 即使你设法使这条线路工作,你会得到一个新的崩溃在别的地方。
主要版本的MSVC之间不保证库二进制兼容性。 STL代码大部分是扩展到您的代码的模板代码。 所以你是静态库可能有不兼容的块内STL代码。
一般来说,这不应该是一个问题,除非STL代码是库的接口的一部分。 例如,如果您将迭代器或引用从一个库传递到另一个库,则会遇到麻烦。
最好的解决方案是用相同版本的编译器构建一切。 如果你不能做到这一点(例如,如果其中一个库来自第三方),你可能会陷入困境。