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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QPluginLoader + Указатель - не находит public методы  (Прочитано 8541 раз)
DarkPhoenix
Гость
« : Май 04, 2010, 14:34 »

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

интерфейс:
Код:
class PluginInterface
{
public:
    virtual void version();
    virtual void path();
    virtual void setMainWnd(MainWindow * prmVal);
};

Код:
class PluginManager
{
public:
    explicit PluginManager();
    static PluginManager* instance();

    void loadPlugins();
    void setMainWnd(MainWindow * prmVal);
private:
    QList<PluginInterface *> plugins;
    MainWindow * mainWnd;

private:
    static PluginManager* _self;
};

Код:
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void echo();

    QWebView * view;

    QWebView * getWebView();

};

инициализация менеджера, установка указателя на текущую форму (MainWindow)
Код:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    view = new QWebView;
    view->load(QUrl("http://ya.ru"));

    setCentralWidget(view);

    PluginManager * pluginmanager = PluginManager::instance();
    pluginmanager->setMainWnd(this);
    pluginmanager->loadPlugins();
}

QWebView * MainWindow::getWebView()
{
    return view;
}

загрузка плагинов
Код:
            gamePlugin = qobject_cast<PluginInterface *>(plugin);
            if (gamePlugin)
            {
                plugins << gamePlugin;
                gamePlugin->setMainWnd(mainWnd);
                gamePlugin->version();
                QMessageBox::information(0,"Plugin manager",fileName);
            }
-----
плагин:

Код:
void TestPlugin2::version()
{
    mainWnd->echo(); // НЕ работает: release/testplugin2.o:testplugin2.cpp::-1: error: undefined reference to `MainWindow::echo()'
    // QWebView * view = mainWnd->getWebView(); // НЕ работает: release/testplugin2.o:testplugin2.cpp::-1: error: undefined reference to `MainWindow::getWebView()'
    QWebView * view = mainWnd->view; // РАБОТАЕТ
    if (view != 0)
    {
        view->load(QUrl("http://yandex.ru"));
    }
    QMessageBox::information(0,"test plugin 2","version");
}

прилагаю исходник проекта.
Записан
Sancho_s_rancho
Гость
« Ответ #1 : Май 04, 2010, 18:14 »

1) У вас в конструкторе главного окна создается PluginManager и в нем экземпляр класса плагина,  плагин в свою очередь вызывает открытый метод главного окна, т.е. главное окно еще не создано до конца, а вы его публичные методы из другого класса дергаете. Нехорошо
2) В интерфейсе плагинов надо включить #include <QtPlugin>. Во всяком случае так говорит документация.
3)Методы класса интерфейса можно объявить чисто виртуальными (=0).
4)Деструктор в интерфейсном классе объявите виртуальным.
Записан
ритт
Гость
« Ответ #2 : Май 05, 2010, 10:03 »

а я вчера поленился тратить время Улыбающийся

@Sancho_s_rancho, зачёт
Записан
DarkPhoenix
Гость
« Ответ #3 : Май 05, 2010, 12:27 »

1) У вас в конструкторе главного окна создается PluginManager и в нем экземпляр класса плагина,  плагин в свою очередь вызывает открытый метод главного окна, т.е. главное окно еще не создано до конца, а вы его публичные методы из другого класса дергаете. Нехорошо
2) В интерфейсе плагинов надо включить #include <QtPlugin>. Во всяком случае так говорит документация.
3)Методы класса интерфейса можно объявить чисто виртуальными (=0).
4)Деструктор в интерфейсном классе объявите виртуальным.

п.1. вынес загрузку плагина в main.cpp (после w.show()Подмигивающий согласен с первоначальной кривизной.
п.2. включил в интерфейс и в реализацию плагина (странно, не заметил это в документации)
п.3. пробовал делать так, не помогло. вернул.
п.4. в интерфейсе объявил: virtual ~PluginInterface() = 0;
в плагине объявил и создал заглушку: ~TestPlugin2();
результат: release/testplugin2.o:testplugin2.cpp::-1: error: undefined reference to `PluginInterface::~PluginInterface()'
Записан
BRE
Гость
« Ответ #4 : Май 05, 2010, 12:36 »

4)Деструктор в интерфейсном классе объявите виртуальным.

п.4. в интерфейсе объявил: virtual ~PluginInterface() = 0;
Так не надо.  Улыбающийся
Лучше так:
virtual ~PluginInterface() {}
Записан
DarkPhoenix
Гость
« Ответ #5 : Май 05, 2010, 12:46 »

Цитировать
Так не надо.  Улыбающийся
Лучше так:
virtual ~PluginInterface() {}

Спасибо помогло Улыбающийся

но: release/testplugin2.o:testplugin2.cpp::-1: error: undefined reference to `MainWindow::getWebView()'
по прежнему есть Грустный
может как-то иначе оформить метод?

Код:
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void echo();
    MainWindow * self();
    QWebView * view;
    QWebView * getWebView();
};
Записан
Sancho_s_rancho
Гость
« Ответ #6 : Май 05, 2010, 14:15 »

Суперприз в студию Код приложи обновленный!
Записан
DarkPhoenix
Гость
« Ответ #7 : Май 05, 2010, 14:18 »

обновил исходник
Записан
DarkPhoenix
Гость
« Ответ #8 : Май 24, 2010, 11:49 »

вопрос по прежнему открыт Грустный
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #9 : Май 24, 2010, 13:13 »

ну вполне логично - у вас главное окно в ДРУГОМ модуле компиляции => его методы из плагна вызывать нельзя (в плагине этих функций нет).
Записан
DarkPhoenix
Гость
« Ответ #10 : Май 24, 2010, 15:53 »

при этом widgets доступны....
странно как-то сделано.
Записан
DarkPhoenix
Гость
« Ответ #11 : Июль 23, 2010, 17:50 »

Повозился с QPluginManager
пришел к выводу что для реализации плагинов более чем "hello world" функционал не пригоден.
Работать с параметрами в виде базовых объектов QT очень не интересно, не функционально.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #12 : Июль 23, 2010, 19:04 »

qobject_cast мы не проходили?
Записан
ритт
Гость
« Ответ #13 : Июль 23, 2010, 20:34 »

каст-кастом, но что толку, если он из плагина в приватную секцию лезет? /* ещё и функционал ему непригоден...Улыбающийся */

@BW, а импорт/экспорт - это для чего, подскажи?
Записан
DarkPhoenix
Гость
« Ответ #14 : Июль 24, 2010, 10:15 »

каст-кастом, но что толку, если он из плагина в приватную секцию лезет? /* ещё и функционал ему непригоден...Улыбающийся */

@BW, а импорт/экспорт - это для чего, подскажи?
пытался вызывать PUBLIC метод, а не PRIVATE
EXPORT - это скорее уже к реализации обычных dll, или ошибаюсь?

qobject_cast мы не проходили?
в моем случае это не нужно.

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


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