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

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

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Загрузка классов из динамических библиотек???  (Прочитано 36848 раз)
ритт
Гость
« Ответ #15 : Январь 14, 2009, 15:27 »

Цитировать
ну так MyModule - есть потомок QThread, и в него мне надо будет добавить дополнительные методы... вот я сразу с "методами что в комментариях" типо и задекларировал его... Улыбающийся

хотя думаю это неправильно, и вообще я так понял тут изза того что имеется такая "фича" как интерфейс - то :
Цитировать
virtual void* MyModuleCreate() ;
   
декларировать наверное ненужно, т.к. можно сделать, чтобы MyModule создавался в конструкторе интерфейса, что-ли....

а уже декларировать в интерфейсе MyModuleInterface нужно такие методы как к примеру:

Start() - запуск модуля
Stop() - останов модуля
State() - статус модуля и т.п,

которые я реализую в классе MyModule   ...

Я правильно мыслю? Улыбающийся
нет.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #16 : Январь 14, 2009, 15:29 »

кстати, в до кучи, а можно ли сделать плагин так, чтобы при его загрузке основным приложением автоматом создавался класс  MyModule и становились доступными его методы?

Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #17 : Январь 14, 2009, 15:36 »

Цитировать
кузулис, похоже, подправил код, пока я отвечал...

дадада  Смеющийся

Цитировать
нет.

блина..   ну тогда я не понимаю нифига  Непонимающий

т.е при загрузке планина - мне придется с помошью задекларированной в интерфейсе ф-ции создать объект "MyModule",
а потом уже воспользоваться задекларированными в интерфейсе функциями - методами этого класса "MyModule" и получается тогда не нужно получать указатель на объект MyModule!!!  Непонимающий

Зы: а теперь тоже неправильно?
Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #18 : Январь 14, 2009, 15:42 »

Цитировать
кстати, в до кучи, а можно ли сделать плагин так, чтобы при его загрузке основным приложением автоматом создавался класс  MyModule и становились доступными его методы?

Конструктор MyModulePlugin к вашим услугам. Только подумайте как указатель на MyModule будет возвращаться наружу и кто его будет удалять. Вообще советую наследовать не от QThread, а от QObject, а потокобезопастный код сделать в основной программе. Из замените:

Код:
virtual void* MyModuleCreate() = 0;

на

Код:
virtual MyModuleBase * MyModuleCreate() = 0;

Где MyModuleBase - абстрактный класс, что обьявлен в основной программе, а плагин всего лишь реализует его.

Ваши методы Start(), Stop(), State() и тому подобное - будут обьявлены в MyModuleBase, а не MyModuleInterface. Чехарда с названиями, легко запутаться, но я думаю вы поняли что к чему. Всё что должен дедать интерфейс плагина - создавать обьект. Точка.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #19 : Январь 14, 2009, 15:49 »

вот переделал по-новому:

это интерфейс *.h
Код:
#ifndef INTERFACES_H
#define INTERFACES_H

class MyModuleInterface
{
public:
    virtual ~MyModuleInterface() {}
    virtual void MyModuleCreate() = 0;
    virtual void MyModuleStart() = 0;
};

Q_DECLARE_INTERFACE(MyModuleInterface, "mywww.My.MyModuleInterface/1.0")

#endif

это хейдер плагина *.h
Код:
#ifndef MYPLUG_H
#define MYPLUG_H

#include <QObject>
#include <QThread>

#include "../app/interfaces.h"

//это собственно определение моего модуля, который должен чо-то выполнять
class MyModule : public QThread
{
    Q_OBJECT

protected:
    void run();
/*
тут добавлю потом в public, private различные необхлдимые мне методы
*/
};

//это как я понял плагин с интерфейсом
class MyModulePlugin : public QObject,
                       public MyModuleInterface
{
    Q_OBJECT
    Q_INTERFACES(MyModuleInterface)

public:
    void MyModuleCreate();
    void MyModuleStart();

private:
    MyModule *Module;
};

#endif

это реализация плагина *.cpp
Код:
#include <QtGui>
#include "myPlug.h"


//
void MyModule::run()
{
    printf("Module is Running \n");
    while (1) {
    /*
    тут будет собственно реализован к примеру алгоритм работы модуля
    */
    }
}

//
void MyModulePlugin::MyModuleCreate()
{
    Module = new MyModule();
}

void MyModulePlugin::MyModuleStart()
{
    Module->start();
}


Q_EXPORT_PLUGIN2(mymoduleplugin, MyModulePlugin)


вот так будет модуль работать Непонимающий?
ЗЫ: компилится без ошибок
« Последнее редактирование: Январь 14, 2009, 15:55 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
ритт
Гость
« Ответ #20 : Январь 14, 2009, 16:04 »

говори-не говори...есть люди, которые учатся исключительно на своих ошибках...

это не плагин, а чёрти-что...но, раз компилится без ошиок и будет работать, пользуй.
какой смысл было делать это в виде либы, если дозволено работать только с одним экземпляром класса...да ещё и через враппы, которые по-человечески доступны в супер-классе?
плуг неюзабелен - сам с ним ещё налюбишься...гг...и сделаешь как предлагалось сразу

упд. поторопился...
вполне вероятно, что и не налюбишься - если этот плагин - единственный Улыбающийся
« Последнее редактирование: Январь 14, 2009, 16:05 от Константин » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

блина.. да как сделать то???

вместо :

Код:
class MyModulePlugin : public QObject,
                       public MyModuleInterface

писать :

Код:
class MyModulePlugin : public QThread, //!!!!!!!!!!!!!!!!!!!!!!!
                       public MyModuleInterface

и в классе MyModulePlugin реализовывать тогда всю функциональность?Непонимающий
типа вубрать вообще класс MyModule и все писать в MyModulePlugin  Непонимающий

или я них.. не пойму
« Последнее редактирование: Январь 14, 2009, 16:16 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #22 : Январь 14, 2009, 16:15 »

Цитировать
это не плагин, а чёрти-что...но, раз компилится без ошиок и будет работать, пользуй.

Улыбающийся именно черти чо!! это я набросал чтобы разобраться в принципах! чисто понять!
Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #23 : Январь 14, 2009, 16:24 »

mainapplication/modulebase.h
Код:
class ModuleBase
{
public:
  void start() = 0;
  void stop() = 0;
  void makeMeHappy() = 0;
};

mainapplication/plugininterface.h
Код:
class ModuleBase;

class PluginInterface
{
public:
  virtual ~PluginInterface() {}
  virtual ModuleBase * create() = 0;
};

Q_DECLARE_INTERFACE(PluginInterface, "www.PluginInterface/1.0")

plugin/myplugin.cpp
Код:
class MyModule : public ModuleBase
{
  void start() { ... }
  void stop() { ... }
  void makeMeHappy() { ... }
};

class MyPlugin : public PluginInterface
{
  MyModule * create() { return new MyModule; }
};

Q_EXPORT_PLUGIN2(myplugin, MyPlugin)
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #24 : Январь 14, 2009, 16:36 »

Это вы привели пример, в котором плагин создает некий объект, и основное приложение может получить указатель на этот объект и работать не через с интерфейсы, а напрямую с объектом? Улыбающийся

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

ArchLinux x86_64 / Win10 64 bit
ритт
Гость
« Ответ #25 : Январь 14, 2009, 16:47 »

> т.е когда плагин создает объект, как черный ящик
позволь вопрос: а в каком потоке плагин создаст этот-самый объект? Улыбающийся

описанное тобой чуть выше - это вовсе и не плагин уже...хочешь _правильный_ плагин, Dendy тебе привёл рабочий пример. не хочешь _правильный_, называй плагином что угодно и делай по-своему Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #26 : Январь 14, 2009, 16:58 »

Цитировать
позволь вопрос: а в каком потоке плагин создаст этот-самый объект? Улыбающийся

эээ..
ну я думал что таким образом:

1. Из приложения гружу плагин
2. Проверяю на соответствие моему декларированному интерфейсу
3. Потом в интерфейсе ищу ф-ю создания объекта void MyModuleCreate() ;
4. "Плагин" создает этот Модуль, который является дочерним классом класса QThread
5. Потом в интерфейсе ищу ф-ю запуска объекта void MyModuleStart() ;
6. Модуль "запускается" в работу

это вкратце Улыбающийся

Цитировать
описанное тобой чуть выше - это вовсе и не плагин
а что же тогда это что я описал?

Записан

ArchLinux x86_64 / Win10 64 bit
ритт
Гость
« Ответ #27 : Январь 14, 2009, 17:07 »

ещё забыл уточнить: кто убивает объект? в твоём "наброске" объект вообще бессмертен...

давай тогда пойдём от обратного? - что _конкретно_ тебе требуется реализовать?
Записан
Dendy
Гость
« Ответ #28 : Январь 14, 2009, 18:36 »

У вас путаница в понимании что такое плагин. Можно долго ходить вокруг да около, называть одними и теми же вещами разные сущности. Но в итоге схема проста:

1. У вас в программе есть некий интерфейс, реализацию которого можно подменить. Это обычный класс, от других ничем не отличается. Будете вы писать наследники этого интерфейса непосредственно у себя в программе, или выненесете их во внешнюю динамическую библиотеку - программе от этого ни холодно, ни жарко. Ей сунули указатель на обьект, она с ним поработала, удалила.

2. Внимание, подмена понятий! То что называется интерфейсом плагина (MyModuleInterface у вас) - это не обьект, который вы будете подменять. Это синглтон для получения обьектов из динамической библиотеки.

Поняли?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #29 : Январь 14, 2009, 20:04 »

Цитировать
ещё забыл уточнить: кто убивает объект? в твоём "наброске" объект вообще бессмертен...
я пока додумался только реализовать ф-ю противоположную void MyModuleCreate() и называться будет void MyModuleDestroy() Улыбающийся
Цитировать
давай тогда пойдём от обратного? - что _конкретно_ тебе требуется реализовать?
... если бы я знал... Улыбающийся
а серьезно - я хочу написать некое приложение (GPL) , наподобие SCADA... Оно бучет состоять из различных подсистем.. Каждая подсистема будет заниматься своим делом... Управлять подсистемами будет "ядро" ... Так вот, суть работы SCADA системы в кратце - сбор данных от различных источников, их обработка, архивирование и т.п. и. т.д.  Источники могут быть различные, например PLC, цифровые преобразователи (датчики), сервера, раб станции и все что угодно... Чтобы поиметь с них информацию - SCADA системе нужно знать что за источник и как с ним общаться....  т.е знать протокол обмена с неким девайсом... 
так вот, я могу впринципе все это реализовать без всяких плагинов, а чисто как некую подсистему приложения которая будет неотделима от него... но это не есть гут... поэтому я думаю эту подсистему вынести в отдельный модуль...

Например для начала хочу реализовать (как самое простое) некий модуль , который подключается к приложению и реализует протокол Modbus RTU... т.е этот модуль (после его подключения к приложению и его регистрации) должен позволять делать с ним следующее:
1. Стартовать его.
2.  Останавливать
3. Конфигурировать
4. Получать его статус , а также статусы его "подмодулей"
Модуль должен в зависимости от того как он сконфигурирован, САМ опрашивать источники данных (девайсы), вести статистику, БД и т.п. и. т.д..

А само приложение может получать нужные другим подсистемам данные от этого загруженного модуля посредством определенного API .. т.е приложению не нужны в принципе указатели на объекты в модуле... Ему нужны только АПИ!!!  (я так пока предварительно решил)

Вот я сам и в растерянности как мне поступить.. либо использовать QLibrary либо QPluginLoader

Я пока предварительно решил QPluginLoader использовать... а API реализовать через интерфейсы!!! Вот я поэтому и напираю на это Улыбающийся

Цитировать
1. У вас в программе есть некий интерфейс, реализацию которого можно подменить. Это обычный класс, от других ничем не отличается. Будете вы писать наследники этого интерфейса непосредственно у себя в программе, или выненесете их во внешнюю динамическую библиотеку - программе от этого ни холодно, ни жарко. Ей сунули указатель на обьект, она с ним поработала, удалила.
Ну в принципе сам модуль будет представлять из себя класс!!! Просто тут дилема, как его использовать.. Улыбающийся я пока и сам не понял чего хочу, поэтому пытаюсь понять идею!

Цитировать
2. Внимание, подмена понятий! То что называется интерфейсом плагина (MyModuleInterface у вас) - это не обьект, который вы будете подменять. Это синглтон для получения обьектов из динамической библиотеки.

ну ДА! Я и не говорил что это объект, объектом в моем случае является MyModule и наверное MyModulePlugin
просто мне непонятен один момент, почему везде в примерах  пишут:

class MyModulePlugin : public QObject,
                       public MyModuleInterface

а не к примеру :


class MyModulePlugin : public QThread, //!!!!!!!!!!!!!!!!!!!!!!!
                       public MyModuleInterface

т.е почему вместо QObject, нельзя подставить другой класс какой нибудь..Непонимающий  ведь сразу можно было б тогда к примеру не реализовывать MyModule, а  весь код написать в MyModuleInterface ...

Или меня опять не туда понесло? Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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