Подтвердить что ты не робот

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 фактически определен.

Что мне делать, чтобы избавиться от этих предупреждений?

Спасибо

4b9b3361

Ответ 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 и добавьте новые директивы соответственно.