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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QPluginLoader. Доступ к классу главной программы из плагина  (Прочитано 3599 раз)
fems
Гость
« : Апрель 08, 2014, 11:07 »

qt 5.2

Написал простейшую программу с подключением простейшего плагина с помощью QPluginLoader. Всё работает, всё хорошо.
Не могу получить доступ из плагина (класса - реализованного от интерфейса) к объекту/классу, класс которого описан в основной программе.

Пробовал создавать объект своего класса в самом интерфейсе,
создал указатель в заголовочном файле, а в конструкторе создаю объект - всегда выскакивает ошибка

Цитировать
....: symbol lookup error: .//../mod/libpluginA.so: undefined symbol: _ZN3OneC1Ev
Для закрытия данного окна нажмите <ВВОД>...

в коде One - это имя класса, остальное не понятно
если объект не создаю, а указатель оставляю, всё работает

задача стоит получить доступ к классу, не к объекту.

Подскажите, что делаю не так, можно ли получить доступ к классам (объектам классов) программы из плагина? может этот момент решается другими путями
« Последнее редактирование: Апрель 08, 2014, 11:24 от fems » Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #1 : Апрель 08, 2014, 11:23 »

Для модуля можно сделать примерно такой интерфейс:
Код:
class IPlugin
{
public:
virtual ~IPlugin1() { }
virtual void pluginInit(Host* host) = 0;
};

Q_DECLARE_INTERFACE(IPlugin, "IPlugin/1.0")

и при создании модуля из главного приложения, вызывать pluginInit, где Host интерфейс вашего главного приложения
Записан
fems
Гость
« Ответ #2 : Апрель 08, 2014, 12:29 »

и при создании модуля из главного приложения, вызывать pluginInit, где Host интерфейс вашего главного приложения
Так же ошибка
При инициализации в pluginInit, объект host - это объект класса, интерфейса или чего именно, вот тут я утонул, перепробовал разные варианты, не идёт

Инициализирую в главном так:
Код:
pI->pluginInit(this);
где this - класс реализованный от интерфейса  главного приложения
« Последнее редактирование: Апрель 08, 2014, 12:30 от fems » Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #3 : Апрель 08, 2014, 12:52 »

Инициализирую в главном так:
Код:
pI->pluginInit(this);
где this - класс реализованный от интерфейса  главного приложения
модуль каким образом знает о this? как описан интерфейс?
Записан
fems
Гость
« Ответ #4 : Апрель 08, 2014, 13:21 »

вложил проект, обрезал до самого минимума, чтобы ничего не мешало
Тестирую на лине убунте, но проблем на винде не должно быть

One - тестовый класс/объект к которому планируется получать доступ

Сейчас рабочая версия, но если в plugina.cpp раскоментировать
Цитировать
qDebug() << parentHost->one->getTt();
то вылезет ошибка
« Последнее редактирование: Апрель 08, 2014, 13:25 от fems » Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #5 : Апрель 08, 2014, 13:50 »

Тестирую на лине убунте
Добавьте к флагам линкера для сборки ядра -export-dynamic, это позволит линкеру экспортировать символы программы и они станут доступны плагину.

но проблем на винде не должно быть
Будут. Улыбающийся
Лучше использовать такое разделение:
main - основная программа
core.dll - общие классы, которые должны использоваться и в main и в плагинах
plagin_xxx.dll - все плагины, которые будут подключать себе core.dll
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #6 : Апрель 08, 2014, 13:56 »

Сейчас рабочая версия, но если в plugina.cpp раскоментировать
Цитировать
qDebug() << parentHost->one->getTt();
то вылезет ошибка

Разберитесь с интерфейсами и реализацией:
Код
C++ (Qt)
class ParserInterface
{
public:
   virtual ~ParserInterface() { }
 
   virtual void pluginInit(ParserInterface *host) = 0;
 
   ParserInterface *parentHost;
 
   One *one;
 
};
Зачем в интерфейс помещать поля: parentHost, и one, их надо вынести в реализацию, а интерфейс сделать таким:

Код
C++ (Qt)
class ParserInterface
{
public:
   virtual ~ParserInterface() { }
 
   virtual void pluginInit(ParserInterface *host) = 0;
   virtual ParserInterface *parentHost() = 0;
   virtual One *one() = 0;
};

соответственно
parentHost(), one() и уйдут в реализацию, проблемы должны уйти
Записан
fems
Гость
« Ответ #7 : Апрель 08, 2014, 14:47 »

Зачем в интерфейс помещать поля: parentHost, и one, их надо вынести в реализацию, а интерфейс сделать таким:
соответственно
parentHost(), one() и уйдут в реализацию, проблемы должны уйти
Не затруднит показать пример, не получается, теперь ругается в main-е, что класс Parser является абстрактным, видимо изза полей.
чтото я не допонял


Лучше использовать такое разделение:
main - основная программа
core.dll - общие классы, которые должны использоваться и в main и в плагинах
plagin_xxx.dll - все плагины, которые будут подключать себе core.dll
Именно этот способ стоял в очереди, но хотелось бы пробраться через плагин Улыбающийся
Записан
fems
Гость
« Ответ #8 : Апрель 08, 2014, 22:02 »

решил сделать по нормальному через библиотеку из которой буду брать классы
помогло http://www.prog.org.ru/topic_8259_0.html

вопрос закрыт, всем спасибо Подмигивающий
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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