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

我正在尝试从包含诸如std :: vectors和std :: strings之类的对象的DLL中导出类-整个类通过以下方式声明为dll导出:


    class DLL_EXPORT FontManager

{

问题是对于复杂类型的成员,我会收到以下警告:


警告C4251:“ FontManager :: m__fonts”:类“ std :: map <_Kty,_Ty>”需要具有“ FontManager”类的客户端使用dll接口,并带有[_Kty = std :: string,_Ty = tFontInfoRef ]


我可以通过以下警告类声明来删除某些警告,即使我没有更改成员变量本身的类型也是如此:


template class DLL_EXPORT std::allocator<tCharGlyphProviderRef>;

template class DLL_EXPORT std::vector<tCharGlyphProviderRef,std::allocator<tCharGlyphProviderRef> >;

std::vector<tCharGlyphProviderRef> m_glyphProviders;

看起来当成员被编译时,前向声明“注入”了DLL_EXPORT,但是它安全吗?当客户端编译此标头并在其一侧使用std容器时,它是否真的更改了任何内容?它会在将来使用这种容器DLL_EXPORT(并且可能不是内联吗?)吗?它真的解决了警告试图警告的问题吗?


我是否应该担心此警告,还是最好在这些结构的范围内将其禁用?客户端和dll将始终使用相同的库和编译器集构建,而这些仅是标头类。


我将Visual Studio 2003与标准STD库一起使用。


----更新----


尽管我认为答案很笼统,但我想将目标更多地作为目标,在这里我们谈论的是std容器和类型(例如std :: string)-也许问题确实是:


我们是否可以通过相同的库标头禁用对客户端和dll都可用的标准容器和类型的警告,并像对待int或任何其他内置类型一样对待它们?(这似乎确实对我有利。)如果可以,那么在什么条件下我们可以做到这一点?


还是应该禁止使用此类容器,或者至少要格外小心,以确保没有赋值运算符,复制构造函数等会内联到dll客户端中?


总的来说,我想知道您是否设计一个具有此类对象的dll接口(例如,使用它们将东西作为返回值类型返回给客户端)是一个好主意,为什么?我想拥有这个功能的“高级”界面...也许最好的解决方案是Neil Butterworth建议的-创建静态库?


C ++ Visual Studio DLL


叮当猫咪
浏览 570回答 3
3回答

一只甜甜圈

该警告告诉您DLL的用户将无法跨DLL边界访问您的容器成员变量。明确导出它们使它们可用,但这是一个好主意吗?通常,我会避免从您的DLL中导出标准容器。如果您完全可以保证您的DLL将与相同的运行时和编译器版本一起使用,则将是安全的。您必须确保使用相同的内存管理器释放在DLL中分配的内存。否则,充其量只能在运行时声明。因此,请勿直接跨DLL边界公开容器。如果需要公开容器元素,请通过访问器方法公开。在您提供的情况下,将接口与实现分开,并在DLL级别公开接口。您对std容器的使用是DLL客户端不需要访问的实现细节。或者,执行Neil的建议并创建一个静态库而不是DLL。您将失去在运行时加载库的能力,并且库的使用者必须在更改库时随时重新链接。如果您可以忍受这些妥协,那么静态库至少可以使您摆脱这个问题。我仍然认为您不必要地公开了实现细节,但这对您的特定库可能有意义。

慕慕森

我发现处理这种情况的最佳方法是:创建您的库,并使用库名称中包含的编译器和stl版本对其进行命名,就像boost库一样。例子:-用于dll版本的FontManager-msvc10-mt.dll,特定于MSVC10编译器,默认为stl。-用于dll版本的FontManager-msvc10_stlport-mt.dll,特定于MSVC10编译器,带有stl端口。-用于dll版本的FontManager-msvc9-mt.dll,特定于MSVC 2008编译器,具有默认的stl-libFontManager-msvc10-mt.lib,用于静态lib版本,特定于MSVC10编译器,具有默认stl。按照这种模式,您将避免与不同的stl实现相关的问题。请记住,vc2008中的stl实现与vc2010中的stl实现不同。使用boost :: config库查看示例:#include <boost/config.hpp>#ifdef BOOST_MSVC#&nbsp; pragma warning( push )#&nbsp; pragma warning( disable: 4251 )#endifclass DLL_EXPORT FontManager{public:&nbsp; &nbsp;std::map<int, std::string> int2string_map;}#ifdef BOOST_MSVC#&nbsp; pragma warning( pop )#endif
打开App,查看更多内容
随时随地看视频慕课网APP