2013-10-12 68 views
0

我知道這個問題已經被多次以類似的方式提出,但我並不積極,我已經完全理解了這裏涉及的概念。我目前正在做一些小型的學習項目(因爲我暫時不再使用C++並希望重新開始使用C++),並且從我讀過的內容來看,在DLL中使用STL時存在一些問題。C++ STL和DLLs

但是,從我收集的有兩種方法可以避免可能的問題。

方法1:DLL的用戶必須具有相同的編譯器和相同的C運行時庫。

方法2:隱藏所有STL類成員不能直接訪問。

然而,當涉及到方法2,我知道STL類成員不能直接通過客戶端對這種方法的工作訪問,但這是否意味着:

//Note all the code in this example was written directly in my web broswer with no checking. 

#ifdef SAMPLEDLL_EXPORTS 
#define SAMPLE_API __declspec(dllexport) 
#else 
#define SAMPLE_API __declspec(dllimport) 
#endif 

class SAMPLE_API SampleClass 
{ 
    std::map<int, std::string> myMap; 

    public: 
    SampleClass(); 
    ~SampleClass(); 

    void addSomething(int in_Key, char* in_Val) 
    { 
    std::string s(in_Val); 
    myMap.insert(std::pair<int, std::string>(in_Key, s)); 
    }; 

    bool getHasKey(int in_Key) 
    { 
     return myMap.find(in_Key) != myMap.end(); 
    }; 

}; 

會的工作?

+2

在這個特定的情況下,是的,因爲所有的代碼都在頭文件中,所以在DLL中沒有任何東西。可能不是你的意思。 –

回答

1

Hans Passant在評論中指出,您的示例有點問題,因爲您將所有方法定義內聯。但是讓我們假設你將定義移動到一個單獨的.cpp文件中,然後將其構建到DLL中。

這將是不安全的。

從一開始就對,我們有這樣的:

class SAMPLE_API SampleClass 
{ 
    std::map<int, std::string> myMap; 

我並不需要進一步研究的任何,因爲我們可以馬上看到該SampleClass的大小取決於的std ::地圖大小,而這並不是標準所規定的。所以,儘管你可以說SampleClass不會「暴露」它的地圖,但它確實有點類似。您可以使用Pimpl技術來克服這一點,並真正將您的課程的ABI隱藏起來。

+0

你介意解釋pimpl是如何工作的嗎?是否因爲地圖僅在pimpl的實現中有效? –

+0

這是因爲映射的大小以及因此impl類的大小隻需要在編譯的DLL中知道,而不是API用戶。這是因爲只有DLL會(分配)impl對象,使用它們等.Pimpl只是更全面地隱藏了實現細節。 –