解决DLL导出class时的4251警告

来源:互联网 发布:mysql镜像站下载 编辑:程序博客网 时间:2024/04/28 04:39
VC2003编译器,在导出DLL中的整个类的成员函数时,如果存在STL类型的成员变量,比如vector、list、map等,则会出现编译警告:
include/glsubject.h|27|warning C4251: 'CGlSubject::m_listObs' : class 'std::list<_Ty>' needs to have dll-interface to be used by clients of class 'CGlSubject'|
原因:
Dll无法直接导出泛型模板(generalized template),因此,如果要导出stl类,则模板必须先实例化(instantiated)。另外,如果导出的STL类使用了其他STL类,那么这些其他类必须同时被导出。目前stl中唯一能够被导出的容器是vector,其他容器(如map、set、queue、list、deque)都因包含嵌套类而不能被导出。
导出STL类的步骤:
1. 在Dll和exe文件中,用同样版本的c运行库链接。譬如都用Msvcrt.lib(release)链接或都用Msvcrtd.lib(debug)链接。
2. Dll中,用__declspec(dllexport)导出模板类的实例。
3. 在exe文件中,用__declspec(dllimport)和extern关键字从Dll中导入 stl类。
详见链接:http://www.vckbase.com/document/viewdoc/?id=1263
经过实践,还有两个方法可以消除该警告。
方法一:只在相应成员函数前面加入__declspec(dllexport)。
方法二:改成指针型定义:
将std::list<CObserver*> m_vecObs;
改成:std::list<CObserver*>* m_pObs;

别忘了在构造函数中动态new,在析构函数中delete:
CGlSubject::CGlSubject() : m_pObs(NULL), m_state(0)
{
  m_pObs = new std::list<CObserver*>();
}

CGlSubject::~CGlSubject()
{
  if (m_pObs != NULL) delete m_pObs;
}
原创粉丝点击