Std::vector должен иметь dll-интерфейс, который будет использоваться клиентами класса X <T> warning
Я пытаюсь сделать мою библиотеку экспортируемой как DLL, но я получаю много этих предупреждений для одного конкретного класса, который использует std::vector:
template <typename T>
class AGUI_CORE_DECLSPEC AguiEvent {
typedef void (*AguiCallbackFptr)(T arg, AguiWidget* sender);
std::vector<AguiCallbackFptr> events;
public:
void call(AguiWidget* sender, T arg) const;
void addHandler(AguiCallbackFptr proc);
void removeHandler(AguiCallbackFptr proc);
void removeHandler();
AguiEvent();
};
Я получаю такие предупреждения:
Предупреждение 57 Предупреждение C4251: "AguiEvent:: events": класс 'std::vector < _Ty > ' должен иметь dll-интерфейс, который будет использоваться клиентами class 'AguiEvent'
Я попытался найти, как это сделать правильно, но документация MSDN - это только "Только Windows", и мне нужно, чтобы это было кросс-платформой, так что она специфична только для MS, когда AGUI_CORE_DECLSPEC фактически определен.
Что мне делать, чтобы избавиться от этих предупреждений?
Спасибо
Ответы
Ответ 1
Экспорт из DLL зависит от платформы. Вам нужно исправить это для Windows (в основном использовать declspec(dllexport/dllimport)
в шаблоне экземпляров класса) и инкапсулировать требуемый код в ваш препроцессор для Windows макрос.
Мой опыт заключается в том, что экспорт классов STL из DLL в Windows чреват болью, обычно я пытаюсь создать интерфейс таким образом, чтобы это не было необходимо.
Ответ 2
Одно исправление полагается на динамическое распределение/освобождение структур STL. Итак:
class EXPORTED ExportedClass
{
private:
std::vector<int> *_integers;
public:
ExportedClass()
{
_integers = new std::vector<int>();
}
~ExportedClass()
{
delete _integers;
}
};
не будет давать никаких предупреждений и более безопасно, если вы распространяете один и тот же двоичный файл (dll), который должен использоваться с другой версией компилятора, который может иметь разные версии STL. Таким образом, у вас есть 100% гарантия того, что sizeof(ExportedClass)
всегда один и тот же.
Ответ 3
Вы можете просто экспортировать элементы, к которым должны обращаться клиенты dll. Для этого удалите декларацию экспорта из объявления класса и добавьте ее в каждую отдельную функцию-член, которую вы хотите экспортировать.
EDIT:
В вашем случае вы, вероятно, не должны пытаться экспортировать класс (оставьте AGUI_CORE_DECLSPEC), так как это класс шаблона. Предоставьте все методы в своем заголовке как встроенные, и он будет работать.
Если вы этого не хотите, некоторые компиляторы предоставляют специальный способ экспорта классов шаблонов. Но вам нужно указать параметр шаблона для этого.
Ответ 4
Обычный метод работы с подобными платформой, например, состоит в том, чтобы попытаться ограничить все специфические для платформы параметры несколькими небольшими файлами/классами низкого уровня, а затем использовать директивы #defines и # ifdef/# ifndef для препроцессора для добавления/замены специфические для платформы варианты.
Чтобы эффективно реализовать это, вам может понадобиться слой абстракции. Например, система производства, над которой я работал в 1990-х годах, имела библиотеку "Файловая система". Это дало общий интерфейс для приложений и производственного кода, но им пришлось полагаться на несколько файлов, специфичных для конкретной платформы. Помимо упрощения компиляции и обслуживания, он также упростил перенос на новые платформы. Новый файловый поставщик оборудования или ОС? Просто добавьте настройки в файлы include и добавьте новые директивы соответственно.