在使用MFC开发DLL时,如果我们导出的类中使用了像CString、string类等模板类的话,就会提示4251的编译警告:
warning: C4251:class“std::basic_string<_Elem,_Traits,_Ax>”需要有 dll 接口由 class“xxx”的客户端使用
该警告可以用两种方法来消除。
1.将工程的MFC使用改为“在共享dll中使用mfc”,编译时就没有了4251的警告信息。
2.如果项目只允许使用“在静态库中使用mfc”,那就在工程中添加以下两个语句:
template class _declspec(dllexport)CStringT
template class _declspec(dllexport)CStringT
template class __declspec(dllexport)std::allocator
class __declspec(dllexport) std::_String_base;
template class __declspec(dllexport) std::_String_val
template class __declspec(dllexport) basic_string
template class __declspec(dllexport)std::allocator
template class __declspec(dllexport)std::vector
1. 情况1
如果类的定义里面仅含有编译器内置的类型变量int, float等等,或者成员函数仅使用了这些变量作为参数,那么很简单,直接将类导出就可以了。
class__declspec(dllexport) YourClass
{
}
2. 情况2
如果类内部使用了别的类,那么别的类最好也导出,不然,首先编译的时候会出现编译警告:
warning C4251: needs to havedll-interface
意思是你使用另外的一些类型/接口,但是这些类型或接口没有导出。当你的client使用这些类型/接口的时候,会出错。
class__declspec(dllexport) YourClass
{
YourAnatherClass m_data; // 这里会出现warning 4251
}
解决办法就是: 在YourAnatherClass定义的地方加上
class__declspec(dllexport) YourAnatherClass
{
}
如上,当你的YourAnatherClass没有导出的时候,dll的使用方会出现链接错误。
3.情况3
当类的内部使用了STL模板的时候,也会出现C4251警告,情况会有所不同
class__declspec(dllexport) YourClass
{
vector
}
上面的使用模板(无论是stl模板,还是自定义模板)的代码,编译dll时会出现C4251警告,但是dll的使用方,却不会出现链接错误。这个因为dll的使用方那里也有一套模板的定义,当他们使用那个vector
#pragma warning(push)
#pragma warning(disable:4251)
//your declarations that cause 4251
#pragma warning(pop)
若想不使用通过关闭警告的方式关闭警告,那么就这样
1)对于用户自定义的模板
template class DLLImportExportMacro SomeTemplate
SomeTemplate
2)对于STL的模板
templateclass DLLImportExportMacro std::allocator
templateclass DLLImportExportMacro std::vector
std::allocator
vector
导出一个类到DLL,其中用到STL,比如 vector < int >
就会有警告:
C4251warning when using stl-classes in the dll-interface
原因是因为STL的类并没有导出。可能出现的问题比如在一个导出类Y中用到一个非导出类X,那么在Y的一个内联函数y_f 可能调用了 X的x_f同样内联的函数;如果不是静态链接X,就会链接失败,因为找不到x_f。