Я пытаюсь экспортировать классы из DLL, содержащие такие объекты, как std::vectors и std:: strings - весь класс объявляется как экспорт dll через:
class DLL_EXPORT FontManager
{
Проблема в том, что для членов сложных типов я получаю это предупреждение:
warning C4251: 'FontManager:: m__fonts': class 'std:: map < _Kty, _Ty > ' должен иметь dll-интерфейс, который будет использоваться клиентами класса 'FontManager' с [ _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-интерфейса, в котором такие объекты (и, например, использование их для возврата материала клиенту в качестве типов возвращаемых значений), является хорошей идеей или нет, и почему-бы я например, иметь интерфейс "высокого уровня" для этой функциональности... возможно, лучшим решением является то, что предложил Нил Баттерворт - создание статической библиотеки?