Russian Qt Forum
Ноябрь 24, 2024, 05:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Не могу загрузить плагин  (Прочитано 7952 раз)
devnikor
Гость
« : Январь 25, 2014, 19:41 »

Здравствуйте. Написал плагин и пытаюсь его загрузить в рантайме с помощью QPluginLoader, но метод instance() возвращает 0. Не подскажете, почему?
Вот интерфейс плагина:
Код:
#include <QtPlugin>
#include <QWidget>

class PluginInterface : public QWidget {

public:
    virtual ~PluginInterface() { }
    virtual void start() = 0;
    virtual void settings() = 0;
    //signal
    virtual void notificationIsReady(const QString& title, const QString& description,
                                 const QString& image) = 0;

};

Q_DECLARE_INTERFACE(PluginInterface, "com.devlab.Notifier.PluginInterface")

Сам плагин:
Код:
#include <PluginInterface.hpp>
#include <QTimer>

class TestPlugin : public PluginInterface {
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.devlab.Notifier.PluginInterface")
    Q_INTERFACES(PluginInterface)

private:
    QTimer* timer;

public:
    TestPlugin();
    virtual ~TestPlugin();
    virtual void start();
    virtual void settings();

signals:
    void notificationIsReady(const QString& title, const QString& description,
                             const QString& image);
private slots:
    void timerSlot();
};

TestPlugin::TestPlugin() {
    timer = new QTimer(this);
    timer->setInterval(1000);
}

TestPlugin::~TestPlugin() {
    delete timer;
}

void TestPlugin::start() {
    connect(timer, &QTimer::timeout, this, &TestPlugin::timerSlot);
    timer->start();
}

void TestPlugin::settings() { }

void TestPlugin::timerSlot() {
    emit notificationIsReady("Test", "It's works", "");
}

Пытаюсь сделать так, чтобы можно было соединить сигнал плагина со слотом своего класса.
Как загружаю:
Код:
QString path("C:/Users/devnikor/Documents/Projects/Notifier/Notifier/plugins/TestPlugin.dll");
    QPluginLoader loader(path);
    QObject* plugin = loader.instance();
    PluginInterface* testPlugin = qobject_cast<PluginInterface*>(plugin);
    connect(testPlugin, SIGNAL(notificationIsReady(QString, QString, QString)),
            this, SLOT(testSlot(QString, QString, QString)));
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Январь 25, 2014, 19:54 »

Нужно добавить Q_EXPORT_PLUGIN2 или Q_EXPORT_PLUGIN Улыбающийся

Пример создания плагина:
http://doc.crossplatform.ru/qt/4.4.3/designer-customwidgetplugin-customwidgetplugin-cpp.html
Записан

Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Январь 25, 2014, 20:02 »

Нужно добавить Q_EXPORT_PLUGIN2 или Q_EXPORT_PLUGIN
Судя по его коду у него Qt5.

Здравствуйте. Написал плагин и пытаюсь его загрузить в рантайме с помощью QPluginLoader, но метод instance() возвращает 0. Не подскажете, почему?
Посмотрите, что за ошибка будет возвращатся после instance. QPluginLoader::errorString()
Записан
devnikor
Гость
« Ответ #3 : Январь 25, 2014, 20:06 »

gil9red, пишу на Qt5, там вроде надо Q_PLUGIN_METADATA

Old, Unknown error  Улыбающийся
Записан
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #4 : Январь 25, 2014, 20:36 »

Для начала попробуйте класс интерфейса без наследования от QWidget
gil9red, пишу на Qt5, там вроде надо Q_PLUGIN_METADATA
Именно так.

Old, Unknown error  Улыбающийся
было подобное на Qt4, проблемы искал отладчиком. В итоге оказалось что не все зависимые либы были найдены
Записан
devnikor
Гость
« Ответ #5 : Январь 25, 2014, 20:49 »

Johnik, тогда в плагине наследовать и интерфейс и QWidget? Мне просто нужно, что бы сигналы работали
Записан
devnikor
Гость
« Ответ #6 : Январь 25, 2014, 20:54 »

Без наследования от QWidget и макроса Q_OBJECT QPluginLoader::errorString() выдает:
Код:
"Plugin verification data mismatch in 'C:/Users/devnikor/Documents/Projects/Notifier/Notifier/plugins/TestPlugin.dll'" 
Записан
devnikor
Гость
« Ответ #7 : Январь 25, 2014, 20:56 »

На всякий случай приложу код в pro файле
Код:
QT += core widgets

TEMPLATE = lib
 CONFIG += plugin
INCLUDEPATH += ../Notifier/Notifier

HEADERS += \
    testplugin.hpp

SOURCES += \
    testplugin.cpp

DESTDIR = ../Notifier/Notifier/plugins
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Январь 25, 2014, 21:01 »

Вы и из TestPlugin убрали наследование от QWidget и Q_OBJECT?
Записан
devnikor
Гость
« Ответ #9 : Январь 25, 2014, 21:05 »

Old, да
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Январь 25, 2014, 21:10 »

В TestPlugin нужно добавить двойное наследование от QWidget и интерфейс, и добавить Q_OBJECT.
Записан
devnikor
Гость
« Ответ #11 : Январь 25, 2014, 21:22 »

Old, сделал, теперь флаг did_load находится в true
но теперь ошибка с connect:
Код:
C:\Users\devnikor\Documents\Projects\Notifier\Notifier\notificationcenter.cpp:35: ошибка: no matching function for call to 'NotificationCenter::connect(PluginInterface*&, const char*, NotificationCenter* const, const char*)'
             this, SLOT(testSlot(const QString&,const QString&,const QString&)));
                                                                               ^

вызов:
Код:
connect(testPlugin, SIGNAL(notificationIsReady(const QString&,const QString&,const QString&)),
            this, SLOT(testSlot(const QString&,const QString&,const QString&)));
Записан
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #12 : Январь 25, 2014, 21:41 »

забудьте пока о connect. Плагин грузится?

по поводу сигналов в плагине, вот тут говорится один из вариантов как это сделать:
http://www.prog.org.ru/topic_5403_0.html
« Последнее редактирование: Январь 25, 2014, 21:42 от Johnik » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Январь 25, 2014, 22:01 »

но теперь ошибка с connect:
Да, сейчас интерфейс не является наследником QObject и не может посылать сигналы, а connect ждет первым параметром указатель на наследника QObject.

Вам нужно разделить ваш код на две сущности:
- объект плагина
- объект работник (который создается объектом плагина).

Вот первый будет не наследник QObject и не сможет использовать сигналы, но он сможет создавать после своей загрузки объект-работник, который уже будет наследником QObject и сможет сигналить. Примеры этого можно посмотреть по ссылке, которую дал Johnik выше.
Записан
devnikor
Гость
« Ответ #14 : Январь 25, 2014, 22:05 »

Спасибо вам всем большое, целый день бился с этой проблемой.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.09 секунд. Запросов: 22.