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