【发布时间】:2010-10-20 12:51:01
【问题描述】:
我正在尝试从包含 std::vectors 和 std::strings 等对象的 DLL 导出类 - 整个类通过以下方式声明为 DLL 导出:
class DLL_EXPORT FontManager {
问题在于,对于复杂类型的成员,我会收到以下警告:
warning C4251: 'FontManager::m__fonts' : class 'std::map<_Kty,_Ty>' needs to have dll-interface to be used by clients of class 'FontManager' with [ _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 将始终使用相同的库和编译器集构建,并且这些都是仅标头类...
我正在使用带有标准 STD 库的 Visual Studio 2003。
更新
我想更多地针对您,因为我看到答案是一般性的,这里我们谈论的是标准容器和类型(例如 std::string) - 也许问题真的是:
我们能否通过相同的库头禁用客户端和 DLL 都可用的标准容器和类型的警告,并像对待 int 或任何其他内置类型一样对待它们? (它似乎在我这边工作正常)
如果是这样,我们可以做到这一点的条件应该是什么?
或者是否应该禁止使用此类容器,或者至少要格外小心以确保没有赋值运算符、复制构造函数等会内联到 DLL 客户端中?
一般来说,我想知道您是否觉得设计一个具有此类对象的 DLL 接口(例如,使用它们将内容作为返回值类型返回给客户端)是一个好主意,为什么,我会喜欢对此功能有一个“高级”接口...
也许最好的解决方案是 Neil Butterworth 建议的 - 创建一个静态库?
【问题讨论】:
标签: c++ visual-studio dll