在构建导出包含ATL :: CString成员的类的DLL时发出警告C4251

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在构建导出包含ATL :: CString成员的类的DLL时发出警告C4251相关的知识,希望对你有一定的参考价值。

我正在将基于ATL的静态库转换为DLL,并且在使用ATL CString类(在atlstr.h中找到)的任何导出类上收到以下警告:

警告C4251:'Foo :: str_':类'ATL :: CStringT'需要让dll接口被'Foo'类的客户端使用

我正确地宣布Foo类通过__declspec(dllexport)导出。这是一个我可以放心忽视的警告,还是我做错了什么? DLL项目设置被设置为与ATL动态链接,但这似乎没有任何区别。

例如:

#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif

// This class is exported from the DLLTest.dll
class DLLTEST_API Foo
{
public:
 Foo();
 CString str_; // WARNING C4251 HERE
};

此DLL的所有客户端也将使用ATL。

答案

This thread给出了我认为更好的答案,Doug Harrison(VC ++ MVP):

当你在dllexported类Y中使用非dllexported类X时会发出[此警告]。这有什么不好的?好吧,假设Y有一个内联函数y_f,它调用属于X的函数x_f,它也不是内联函数。如果在某个不静态链接X的客户端内部内联y_f,则链接将失败,因为将找不到x_f。

另一答案

这个Microsoft页面帮助了我。

How to export an instantiation of a Standard Template Library (STL) class and a class that contains a data member that is an STL object

另一答案

Here is a thread对此进行了很好的讨论。

简而言之,编译器警告您,实际上,导出的类不会将接口与实现分离。如果客户无法访问相关成员,请将其设为私有,并将#pragma警告该成员/班级。如果成员可供客户端访问和使用,那么您将需要通过访问者和更改者提供对成员的间接访问。

另一答案

当我犯了使用运行时库Single / Multithreaded而不是Single / MultithreadedDLL构建DLL的愚蠢错误时,我通常会收到此警告。您可能想在项目设置中检查它。

以上是关于在构建导出包含ATL :: CString成员的类的DLL时发出警告C4251的主要内容,如果未能解决你的问题,请参考以下文章

包含具有 CString 成员变量的类的集合仅存储首字母

构建 ATL 项目

从 DLL 导出包含 `std::` 对象(矢量、地图等)的类

从 DLL 导出包含 `std::` 对象(矢量、地图等)的类

从 C++ dll 导出一个类?

C++/MFC/ATL 线程安全字符串读/写