2010-08-31 78 views
8

在庫中使用一個符合標準的STL是否安全並且使用該庫的項目中使用另一個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 ::線程的東西。但是如果是這樣的話,我該如何在一個編譯器中編譯一個庫,並讓庫用戶自由地爲他們的項目選擇他們喜歡的編譯器?

+0

Windows/MinWG n00b問:爲什麼不能在MinGW中使用VS STL? – Dummy00001 2010-08-31 14:01:48

+4

標題不應該像「在單個項目中使用多個標準庫」一樣嗎?被閉源與被問到的實際問題似乎不相關。 – 2010-08-31 14:02:33

+0

@Mark B 我指定了「閉源」,因爲客戶可以使用他們喜歡的任何STL來編譯開源庫,所以肯定沒有問題。 – user418680 2010-08-31 14:49:01

回答

6

如果 - 按庫 - 你的意思是動態庫 - 簡單的答案是:不,複雜的答案是:不。

C++和動態庫是一個非常非常脆弱的前景。任何小的更改都需要重建所有模塊,並且每個庫使用的運行時必須是完全相同的庫實例。

即使您設法通過dll邊界獲取std :: string,而std :: string的外部接口已修復,但任何實現差異都會導致數據損壞。

如果運行時間可能不同,那麼在動態庫之間傳遞簡單的POD結構和本地數據類型是安全的 - 即使必須小心正確管理對象生命週期 - 分配庫必須是解除分配庫。

如果你的意思是靜態庫 - 這不會產生大量的意義 - 我不認爲由MinGW所做的庫將與MSDev兼容,並且MSDev庫與MinGW不兼容。即使lib文件格式名義上是兼容的 - 假設不同的名稱格式不會阻止成功的語言:將使用最終鏈接環境的STL庫。

4

這取決於圖書館,平臺,以及如何編譯和鏈接它。通常(特別是在Windows上)庫以DLL的形式分發,並且關於可以在邊界上的內容以及如何編譯每個庫都有非常特定的規則。

升壓,例如,構建的DLL爲:

  • 單線程或多線程
  • 調試或釋放
  • 靜態的(IIb)的或動態的(DLL)
  • 針對每個不同的編譯器和
  • 版本

查看http://beta.boost.org/doc/libs/1_36_0/more/getting_started/windows.html#library-naming的排列組合。

所以是的,這是一個很大的問題。

+1

,並沒有將它們放在WinSxS中。壞! – 2010-08-31 13:47:18

6

在庫中使用一個符合標準的STL是否安全,而在使用該庫的項目中使用另一個STL是安全的?

STL爲可重用性的某些部分被放入一個共享庫。不可能保證類的內部結構在不同的STL中匹配,因此如果兩個程序可以互換使用,就會導致零星的崩潰。

另請注意,來自不同供應商的STL可能具有不同的內部命名空間和類的組織結構。這樣做的結果是公共符號std::basic_string可能具有不同的內部名稱,並且會有不同的錯位,從鏈接器角度看void Foo(std::string& str_mingw);void Foo(std::string& str_vstudio);兩個不同的函數。

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字符串。