2014-10-02 101 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(); 
}