在闭源库中使用STL

时间:2010-08-31 13:38:03

标签: c++ stl

在库中使用一个符合标准的STL是否安全,在使用该库的项目中使用另一个?例如:

//library.h

#include <string>  //let's say here it uses minGW STL

void Foo(std::string& str_mingw);

//library.cpp
void Foo(std::string& str_mingw) { /*do something*/ }



//application.cpp

#include "library.h"
#include <string>  //let's say here it uses VStudio STL

void Bar()
{
  std::string str_vstudio;
  Foo(str_vstudio);
  //Foo() inside the .lib or .dll uses string from minGW,
  //but here a string from VStudio is used
}

在我看来,糟糕的事情会发生,特别是如果使用的不是简单的字符串,而是像tr2 :: thread更复杂的东西。但如果是这样,我如何在一个编译器中编译库并让库用户自由选择他们喜欢的项目编译器?

4 个答案:

答案 0 :(得分:6)

  

在库中使用一个符合标准的STL是否安全,在使用该库的项目中使用另一个?

没有

可重用性的STL的某些部分放入共享库中。不可能保证类的内部结构在不同的STL中匹配,从而导致零星的崩溃,如果程序可以互换使用它们。

另请注意,来自不同供应商的STL可能具有不同的内部命名空间和类的组织。这会导致公共符号std::basic_string可能具有不同的内部名称,并且会被不同地修改,使得void Foo(std::string& str_mingw);void Foo(std::string& str_vstudio);从链接器角度看两个不同的函数。

答案 1 :(得分:6)

如果 - 按库 - 你的意思是动态库 - 简单的答案是:不,复杂的答案是:不。

C ++和动态库是一个非常脆弱的前景。任何小的更改都需要重建所有模块,每个库使用的运行时必须是完全相同的库实例。

即使你设法在dll边界上获得一个std :: string - 而std :: string的外部接口是固定的,任何实现差异都会使数据看起来已损坏。

如果运行时可能不同,那么在动态库之间传递简单的POD结构和本机数据类型是安全的 - 甚至必须小心正确地管理对象生存期 - 分配库必须是解除分配的库。

如果你的意思是静态库 - 这没有多大意义 - 我不认为MinGW制作的libs将与MSDev兼容,MSDev libs与MinGW不兼容。即使lib文件格式在名义上是兼容的 - 假设不同的名称修改不会导致阻止成功的语言:将使用最终链接环境的STL库。

答案 2 :(得分:4)

这取决于库,平台以及如何编译和链接它。通常(特别是在Windows上)库作为DLL分发,并且有关于边界上可能存在的内容以及每个需要如何编译的非常具体的规则。

例如,

Boost构建了以下的DLL:

  • 单线程或多线程
  • 调试或发布
  • 静态(lib)或动态(DLL)
  • 用于每个不同的编译器和版本

有关排列,请参阅http://beta.boost.org/doc/libs/1_36_0/more/getting_started/windows.html#library-naming

是的,这是一个大问题。

答案 3 :(得分:1)

  

使用一种标准是否安全   符合STL的库,和   另一个在使用它的项目中   图书馆? ...... void Foo(std::string& str_mingw); ... Foo(str_vstudio);

没有。它甚至与动态库没有多大关系。即使你设法以某种方式将MS std :: string和MinGW std :: string链接到同一个可执行文件中,它仍会破坏。你的程序中有两个独立的(可能是不同的)std :: string定义,如果你混合它们,你就处于未定义的行为中。

但请注意,如果您的std :: string未在界面中使用,它将起作用。那就是:只要在接口级使用const char *(作为示例),就可以在内部使用一个使用MinGW字符串的库和另一个在内部使用VC字符串的库。