2014-10-02 99 views
2

我有一個dll內的C++類。std :: stringstream類需要有dll接口

在那個類中,我想將來自Curl回調的數據存儲到成員變量中。 我打算用像這樣一個字符串流:

void MyClass::CurlCallback(void * pvData, size_t tSize) 
{ 
    const char* data = static_cast<const char*>(pvData); 

    m_myStringStream << sata; 
} 

但是,當我在類中聲明的stringstream的,像這樣:

private: 
std::stringstream m_myStringStream; 

我收到以下錯誤:

Error 1 error C2220: warning treated as error - no 'object' file generated 
Warning 2 warning C4251: 'MyClass::MyClass::m_myStringStream' : class  'std::basic_stringstream<_Elem,_Traits,_Alloc>' needs to have dll-interface to be used by clients of class 'MyClass::MyClass' 

如何我可以聲明這個stringstream沒有得到這個錯誤?

我認爲這是因爲stringstream是一個C++變量,但dll期待c樣式變量。

我已經調查也許創造,存儲,像這樣的XML數據的類:

class XMLData 
    { 
    public: 
     XMLData(); 
     virtual ~ XMLData(); 

     const char* GetXMLData() const { return xml; } 
     void Append(const char* xmlData) { /*add xmlData to xml blah blah*/}; 

    private: 
     //Add more here - to do 

     char* xml; 
     int length; 
    }; 

,並宣佈它:

XMLData* m_xmlData; 

什麼是做到這一點的最好辦法?

+3

假設你在'MyClass'類中標記了'declspec(dllexport)'屬性,因爲這可以解釋這個消息。你的假設是錯誤的('std :: stringstream'是一個*類型*;不是一個變量)。你的類從你的DLL中導出(並推斷它的成員)。如果你願意的話,你可以旋轉一個皮條來抵消這個(看起來像你)。這是[**這個問題**]的副本(http://stackoverflow.com/questions/4145605/stdvector-needs-to-have-dll-interface-to-be-used-by-clients-of- class-xt-war),順便說一句。 – WhozCraig 2014-10-02 09:55:26

回答

1

首先,您會收到警告,您會選擇在項目設置中威脅所有警告,如錯誤。

DLL導出的類不應該在其導出的接口中聲明覆雜類型(如STL模板),因爲它將DLL的使用限制在相同版本的編譯器中。這就是爲什麼你得到警告。

要解決這個問題,您應該只導出一個接口類(即純粹的抽象類)並返回接口的實現。

這樣的:

//in the interface: 
class DLL_API IMyClass 
{ 
    public: 
    virtual void set(const char* data)=0; 
    virtual const char* get()=0; 
} 

//now not in the interface: 
class CMyClass : public IMyClass 
{ 
private: 
    std::stringstream mystream; 
public: 
    virtual void set(const char* data){ 
    mystream<<data; 
    } 
    virtual const char* get(){ 
     return mystream.str().c_str(); 
    } 
} 

而你只用引用或指針的DLL外,如果你需要在你需要一個工廠方法在DLL中的可執行文件來創建對象,因爲它只知道接口。

IMyClass* ObjectFactory::GetMyClass() 
{ 
    return new CMyClass(); 
}