std :: vector должен иметь dll-интерфейс для использования клиентами класса 'X <T>warning - PullRequest
40 голосов
/ 10 ноября 2010

Я пытаюсь сделать мою библиотеку экспортируемой как 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-интерфейс для использования клиентами класс 'AguiEvent'

Я пытался найти, как это сделать правильно, но документация MSDN очень подходит только для Windows, и мне нужно, чтобы она была кроссплатформенной, чтобы она выполняла специфические для MS вещи, только когда AGUI_CORE_DECLSPEC фактически определено.

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

Спасибо

Ответы [ 4 ]

37 голосов
/ 10 ноября 2010

Экспорт из DLL зависит от платформы.Вам нужно будет исправить это для Windows (в основном используйте declspec(dllexport/dllimport) в созданном шаблоне класса) и инкапсулировать необходимый код в свой макрос препроцессора для Windows.

Мой опыт заключается в том, что экспортКлассы STL из DLL на Windows чреваты болью, обычно я стараюсь спроектировать интерфейс так, чтобы он не был нужен.

32 голосов
/ 29 июля 2011

Одно из исправлений основано на динамическом распределении / освобождении структур STL.Итак:

class EXPORTED ExportedClass
{
private:
    std::vector<int> *_integers;
public:
    ExportedClass()
    {
        _integers = new std::vector<int>();
    }
    ~ExportedClass()
    {
        delete _integers;
    }
};

не будет выдавать никаких предупреждений, и это более безопасно, если вы распространяете один и тот же двоичный файл (dll), который должен использоваться с другой версией компилятора, который может иметь разные версииSTL.Таким образом, у вас есть 100% гарантия того, что sizeof(ExportedClass) всегда одинаков.

8 голосов
/ 10 ноября 2010

Вы можете просто экспортировать участников, к которым должны обращаться dll-клиенты. Для этого удалите объявление экспорта из объявления класса и добавьте его к каждой отдельной функции-члену, которую вы хотите экспортировать.

EDIT:

В вашем случае вам, вероятно, не следует пытаться экспортировать класс (не указывайте AGUI_CORE_DECLSPEC), поскольку это класс шаблона. Укажите все методы в вашем заголовке как встроенные, и они будут работать.

Если вы не хотите этого, некоторые компиляторы предоставляют специальный способ экспорта шаблонных классов. Но для этого вам нужно будет указать параметр шаблона.

2 голосов
/ 10 ноября 2010

Обычный метод работы с подобными платформой вещами состоит в том, чтобы попытаться ограничить все специфичные для платформы настройки несколькими файлами / классами низкого уровня, а затем использовать директивы препроцессора #defines и # ifdef / # ifndef для добавления / замены. Варианты, специфичные для платформы.

Чтобы эффективно реализовать это, вам может понадобиться слой абстракции. Например, производственная система, над которой я работал в 1990-х годах, имела библиотеку «Файловая система». Это представляло общий интерфейс для приложений и производственного кода, но должно было полагаться на несколько платформо-зависимых файлов. Помимо упрощения компиляции и поддержки, он также облегчает перенос на новые платформы. Новый производитель файлового оборудования или версия ОС? Просто добавьте настройки во включаемые файлы и добавьте новые директивы соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...