Название: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 09:17 Доброго времени суток!
Подскажите пожалуйста, каким образом можно загрузить класс из динамической библиотеки, используя механизмы QT4? Я почитал документацию, и нашел только 2 класса QPluginLoader и QLibrary. Но как я понял с помощью них можно релизовать только вызов функций (по примерам из QT). ЗЫ: мне нужно в библиотеку засунуть QT-шный класс (например QThread и т.д) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: lit-uriy от Январь 14, 2009, 09:36 почитай тут (http://www.prog.org.ru/topic_8259_0.html)
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Rcus от Январь 14, 2009, 09:41 Руководство по созданию плагинов:
http://doc.trolltech.com/4.4/plugins-howto.html Пример: http://doc.trolltech.com/4.4/tools-plugandpaint.html Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 10:21 Я это читал, даже пробовал .. это все работает, но мне нужно нечто другое (я так думаю)
Суть: мне к моей проге нужно сделать "подключаемый модуль" (скорее всего плагин :) ) который работает сам по себе и реализует некий потокол (к примеру конкретно Modbus) ... т.е если бы я делал этот модуль не плагином - то он бы представлял из себя экземпляр класса типа QThread, который я бы запускал из основной программы, а сам этот класс работал бы сам по себе вечно там в цикле и чо-то делал по некому алгоритму! :) но как такое же самое проделать, но сделав мой класс - плагином я пока затрудняюсь придумать ! т.е. мне нужно из библиотеки "выдернуть" класс (который является наследником QThread к примеру)... в примерах Assistent , Examples и т.п. "выдергиваются" функции!!! и попутно вопрос, в чем разница по сути использования QPluginLoader и QLibrary??? если и там и там при загрузке мы в конечном итоге выдергиваем из *.dll / *.so нужные нам ф-ции??? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kirill от Январь 14, 2009, 10:30 В либе должна быть функция которая возвратит указатель на этот класс.
Дальше обращаешся к нему из основной программы, приведя void к нужному типу. Например: Код
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 10:55 автору нужно наследника кутред -> плагин будет линковаться с кутэкоре -> можно обойтись без приведения воидстар к нужному типу.
минималистичный вариант может ограничиться строкой: Код: QThread* createObject(QObject* parent) const { return new MyThread(parent); } Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 11:52 to kirill, константин
спс за наводку! :) Цитировать В либе должна быть функция которая возвратит указатель на этот класс. т.е как тут где - то на форумах написано - нужно в либе сделать функцию, при вызове которой - она возвращала класс?? типа этого: Код: //либа .h или как? и: Цитировать автору нужно наследника кутред -> плагин будет линковаться с кутэкоре -> можно обойтись без приведения воидстар к нужному типу. минималистичный вариант может ограничиться строкой: Код: QThread* createObject(QObject* parent) const { return new MyThread(parent); } но это ещё не будет плагином - плагин должен содержать некий интерфейс, известный приложению -> читать ассистант по QPlugin, QPluginLoader, plug & paint example, etc. 1. так в чем существенная разница м/у библой плагина и просто библой с функциями? 2. и как лучше мне поступить в моем случае: создать "модуль" как плагин или просто как обычную библу? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kirill от Январь 14, 2009, 12:29 нужно в либе сделать функцию, при вызове которой - она возвращала класс У тебя дб функция которая создаст класс и вернет указатель на него. То что ты написал не совсем верно. Надо примерно так: Вызывать из основной программы будешь функцию Код: IMPORT_EXPORT void * _CreateThread(/* параметры*/); Код Получив этот указатель в основной программе конвертишь его из void * в MyClass *. Я так делал для QWidget, насколько это верно для QThread не знаю, слушай Константина. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 13:49 ррр...господа, читайте внимательнее.
Код: //либа .h так получаем либу, из которой будем дёргать createObject для получения QThread*. если приложение линкуется с этой либой, советую в хедере оставить лишь Код: class QObject; фактически плагин отличается от либы лишь специальными функциями для {,де}инициализации, проверки версий и т.д. QPlugin скрывает эти функции от пользователя - остаётся лишь обозначить интерфейс и сам плагин через определённые макросы. в итоге видимая разница между плагином и либой - для подключения либы нужен её хедер; для подгрузки плагина нужен только хедер интерфейса (обычно чисто-абстрактный), т.к. интерфейс определяется на стороне сервера, а не на сторонее клиента (либы). ещё вопросы? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 13:52 В общем решил сделать свой подключаемый модуль плагином....
вот код interfaces.h Код: #ifndef INTERFACES_H вот код myPlug.h Код: #ifndef MYPLUG_H вот код myPlug.cpp Код: #include <QtGui> компилирую пока под Windows XP при помощи MinGW и компилятор выдает следующее: Цитировать Creating library file: release\libplug.a release\moc_myPlug.o(.text$_ZN14MyModulePluginD1Ev[MyModulePlugin::~MyModulePlug in()]+0x12):moc_myPlug.cpp: undefined reference to `vtable for MyModuleInterface ' release\moc_myPlug.o(.text$_ZN14MyModulePluginD0Ev[MyModulePlugin::~MyModulePlug in()]+0x13):moc_myPlug.cpp: undefined reference to `vtable for MyModuleInterface ' collect2: ld returned 1 exit status mingw32-make[1]: *** [release\plug.dll] Error 1 mingw32-make[1]: Leaving directory `D:/projects/plg2/lib' mingw32-make: *** [release] Error 2 Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 14:36 /* чуть не нагрубил */
на кой хрен в interfaces.h MyModuleInterface имеет чисто-виртуальный типизированный конструктор? бред! зачем в myPlug.h задекларирован MyModule, если вне плагина он использоваться не будет (будет использоваться суперкласс - QThread)? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 14, 2009, 15:10 /* чуть не нагрубил */ Закройте глаза, расслабьтесь, глубокий вход... на кой хрен в interfaces.h MyModuleInterface имеет чисто-виртуальный типизированный конструктор? бред! Ваше сознание проясняется, вы уже видите знак тильды, говорящий что это деструктор. Виртуальный деструктор это хорошо, это правильно, вы чувствуете блаженство. зачем в myPlug.h задекларирован MyModule, если вне плагина он использоваться не будет (будет использоваться суперкласс - QThread)? Вы чувствуете как поток тёплой энергии расходится по вашему телу. 2 kuzulis : Наверное вы забыли написать тело MyModuleInterface::MyModuleCreate(); 2 Константин: Выдыхаем. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 15:10 в общем плагин собирается если вместо:
Код: virtual void* MyModuleCreate() ;//const = 0; написать: Код: virtual void* MyModuleCreate() = 0; Цитировать на кой хрен в interfaces.h MyModuleInterface имеет чисто-виртуальный типизированный конструктор? бред! деструктор! так написано в доке! что в хейдере интерфейсов должны быть чисто виртуальные ф-ции! и необходимо объявлять только деструктор! ::)Цитировать зачем в myPlug.h задекларирован MyModule, если вне плагина он использоваться не будет (будет использоваться суперкласс - QThread)? ну так MyModule - есть потомок QThread, и в него мне надо будет добавить дополнительные методы... вот я сразу с "методами что в комментариях" типо и задекларировал его... :)Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 15:21 Цитировать ну так MyModule - есть потомок QThread, и в него мне надо будет добавить дополнительные методы... вот я сразу с "методами что в комментариях" типо и задекларировал его... Улыбающийся хотя думаю это неправильно, и вообще я так понял тут изза того что имеется такая "фича" как интерфейс - то : Цитировать virtual void* MyModuleCreate() ; декларировать наверное ненужно, т.к. можно сделать, чтобы MyModule создавался в конструкторе интерфейса, что-ли.... а уже декларировать в интерфейсе MyModuleInterface нужно такие методы как к примеру: Start() - запуск модуля Stop() - останов модуля State() - статус модуля и т.п, которые я реализую в классе MyModule ... Я правильно мыслю? :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 15:26 кузулис, похоже, подправил код, пока я отвечал...
изначально там было Код: class MyModuleInterface 2Dendy, "глубокий вход" - это сильно :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 15:27 Цитировать ну так MyModule - есть потомок QThread, и в него мне надо будет добавить дополнительные методы... вот я сразу с "методами что в комментариях" типо и задекларировал его... Улыбающийся хотя думаю это неправильно, и вообще я так понял тут изза того что имеется такая "фича" как интерфейс - то : Цитировать virtual void* MyModuleCreate() ; декларировать наверное ненужно, т.к. можно сделать, чтобы MyModule создавался в конструкторе интерфейса, что-ли.... а уже декларировать в интерфейсе MyModuleInterface нужно такие методы как к примеру: Start() - запуск модуля Stop() - останов модуля State() - статус модуля и т.п, которые я реализую в классе MyModule ... Я правильно мыслю? :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 15:29 кстати, в до кучи, а можно ли сделать плагин так, чтобы при его загрузке основным приложением автоматом создавался класс MyModule и становились доступными его методы?
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 15:36 Цитировать кузулис, похоже, подправил код, пока я отвечал... дадада ;D Цитировать нет. блина.. ну тогда я не понимаю нифига ??? т.е при загрузке планина - мне придется с помошью задекларированной в интерфейсе ф-ции создать объект "MyModule", а потом уже воспользоваться задекларированными в интерфейсе функциями - методами этого класса "MyModule" и получается тогда не нужно получать указатель на объект MyModule!!! ??? Зы: а теперь тоже неправильно? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 14, 2009, 15:42 Цитировать кстати, в до кучи, а можно ли сделать плагин так, чтобы при его загрузке основным приложением автоматом создавался класс MyModule и становились доступными его методы? Конструктор MyModulePlugin к вашим услугам. Только подумайте как указатель на MyModule будет возвращаться наружу и кто его будет удалять. Вообще советую наследовать не от QThread, а от QObject, а потокобезопастный код сделать в основной программе. Из замените: Код: virtual void* MyModuleCreate() = 0; на Код: virtual MyModuleBase * MyModuleCreate() = 0; Где MyModuleBase - абстрактный класс, что обьявлен в основной программе, а плагин всего лишь реализует его. Ваши методы Start(), Stop(), State() и тому подобное - будут обьявлены в MyModuleBase, а не MyModuleInterface. Чехарда с названиями, легко запутаться, но я думаю вы поняли что к чему. Всё что должен дедать интерфейс плагина - создавать обьект. Точка. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 15:49 вот переделал по-новому:
это интерфейс *.h Код: #ifndef INTERFACES_H это хейдер плагина *.h Код: #ifndef MYPLUG_H это реализация плагина *.cpp Код: #include <QtGui> вот так будет модуль работать ???? ЗЫ: компилится без ошибок Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 16:04 говори-не говори...есть люди, которые учатся исключительно на своих ошибках...
это не плагин, а чёрти-что...но, раз компилится без ошиок и будет работать, пользуй. какой смысл было делать это в виде либы, если дозволено работать только с одним экземпляром класса...да ещё и через враппы, которые по-человечески доступны в супер-классе? плуг неюзабелен - сам с ним ещё налюбишься...гг...и сделаешь как предлагалось сразу упд. поторопился... вполне вероятно, что и не налюбишься - если этот плагин - единственный :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 16:14 блина.. да как сделать то???
вместо : Код: class MyModulePlugin : public QObject, писать : Код: class MyModulePlugin : public QThread, //!!!!!!!!!!!!!!!!!!!!!!! и в классе MyModulePlugin реализовывать тогда всю функциональность???? типа вубрать вообще класс MyModule и все писать в MyModulePlugin ??? или я них.. не пойму Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 16:15 Цитировать это не плагин, а чёрти-что...но, раз компилится без ошиок и будет работать, пользуй. :) именно черти чо!! это я набросал чтобы разобраться в принципах! чисто понять! Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 14, 2009, 16:24 mainapplication/modulebase.h
Код: class ModuleBase mainapplication/plugininterface.h Код: class ModuleBase; plugin/myplugin.cpp Код: class MyModule : public ModuleBase Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 16:36 Это вы привели пример, в котором плагин создает некий объект, и основное приложение может получить указатель на этот объект и работать не через с интерфейсы, а напрямую с объектом? :)
если это так, то я подразумевал иную картину... т.е когда плагин создает объект, как черный ящик.. и приложению не нужно знать чо это за ящик... оно "общается" с объектом посредством ф-й , которые в интерфейсе объявлены! Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 16:47 > т.е когда плагин создает объект, как черный ящик
позволь вопрос: а в каком потоке плагин создаст этот-самый объект? :) описанное тобой чуть выше - это вовсе и не плагин уже...хочешь _правильный_ плагин, Dendy тебе привёл рабочий пример. не хочешь _правильный_, называй плагином что угодно и делай по-своему :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 14, 2009, 16:58 Цитировать позволь вопрос: а в каком потоке плагин создаст этот-самый объект? Улыбающийся эээ.. ну я думал что таким образом: 1. Из приложения гружу плагин 2. Проверяю на соответствие моему декларированному интерфейсу 3. Потом в интерфейсе ищу ф-ю создания объекта void MyModuleCreate() ; 4. "Плагин" создает этот Модуль, который является дочерним классом класса QThread 5. Потом в интерфейсе ищу ф-ю запуска объекта void MyModuleStart() ; 6. Модуль "запускается" в работу это вкратце :) Цитировать описанное тобой чуть выше - это вовсе и не плагин а что же тогда это что я описал?Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 17:07 ещё забыл уточнить: кто убивает объект? в твоём "наброске" объект вообще бессмертен...
давай тогда пойдём от обратного? - что _конкретно_ тебе требуется реализовать? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 14, 2009, 18:36 У вас путаница в понимании что такое плагин. Можно долго ходить вокруг да около, называть одними и теми же вещами разные сущности. Но в итоге схема проста:
1. У вас в программе есть некий интерфейс, реализацию которого можно подменить. Это обычный класс, от других ничем не отличается. Будете вы писать наследники этого интерфейса непосредственно у себя в программе, или выненесете их во внешнюю динамическую библиотеку - программе от этого ни холодно, ни жарко. Ей сунули указатель на обьект, она с ним поработала, удалила. 2. Внимание, подмена понятий! То что называется интерфейсом плагина (MyModuleInterface у вас) - это не обьект, который вы будете подменять. Это синглтон для получения обьектов из динамической библиотеки. Поняли? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 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 ... Или меня опять не туда понесло? :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 14, 2009, 21:57 Вы говорите "ну ДА!" и тут же описываете всё наоборот. От QObject'а интерфейс наследуется только зачем чтобы сделать qobject_cast() и убедиться что загрузили ту ДЛЛ что хотели. Точка. Это не плагин! Это - менеджер плагина, загрузчик, называйте его как хотите. Пусть вас не вводит в заблуждение что он отнаследован от QObject. Всё что этот менеджер должен сделать - создать вам ваш реальный плагин с помощью вызова create() или как вам заблагорассудится его назвать. Можете в его интерфейс включить получение номера версии ДЛЛ. Но никак не сам функционал.
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 14, 2009, 23:59 вот поэтому и просил читать внимательнее...я же ещё на первой странице описывал плагины кутэ - скрытые инициализаторы -> интерфейс -> объект. интерфейс нужен для выбора метода работы с плагином (здесь под плагином я понимаю объект, унаследованный от интерфейса). в частности интерфейс может быть интерфейсом-фабрикой других интерфейсов (или фабрикой фабрик - извращаться можно как угодно). по сути сам интерфейс нужен лишь на этапе "знакомства" с дллкой (часто он может содержать информацию о плагине, авторе и т.п. - чтобы потом можно было отобразить в списке плагинов или в менюшке). а вот объект, с которым основная программа (сервер) будет работать, должен быть создан этой фабрикой. и если мы не хотим выдумывать колесо аки MyModuleDestroy, наследуем оъект от QObject и передаём в конструктор родителя (как я указывал на первой странице). здесь существует ещё один фактор - родительский поток - чтобы избежать нежелательных ситуаций, когда по каким-то причинам объект создался не в том потоке и наглухо блокирует обращения к нему и т.п., гораздо проще не вызывать обёртку-конструктор из нужного потока (как в твоём наброске), а указать родителя - объект переместится в родительский поток (главный поток для (родитель == 0)).
а вот абстракция (MyModuleBase в примере Dendy) - это и есть то, что тебе нужно! в фабрике ты создашь экземпляр произвольного наследника данного абстракта и будешь работать с ним по методам, описанным в декларации абстракта. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Steven_Orko от Январь 15, 2009, 10:10 а серьезно - я хочу написать некое приложение (GPL) , наподобие SCADA... Оно бучет состоять из различных подсистем.. Каждая подсистема будет заниматься своим делом... Управлять подсистемами будет "ядро" ... Так вот, суть работы SCADA системы в кратце - сбор данных от различных источников, их обработка, архивирование и т.п. и. т.д. Источники могут быть различные, например PLC, цифровые преобразователи (датчики), сервера, раб станции и все что угодно... Чтобы поиметь с них информацию - SCADA системе нужно знать что за источник и как с ним общаться.... т.е знать протокол обмена с неким девайсом... так вот, я могу впринципе все это реализовать без всяких плагинов, а чисто как некую подсистему приложения которая будет неотделима от него... но это не есть гут... поэтому я думаю эту подсистему вынести в отдельный модуль... Например для начала хочу реализовать (как самое простое) некий модуль , который подключается к приложению и реализует протокол Modbus RTU... т.е этот модуль (после его подключения к приложению и его регистрации) должен позволять делать с ним следующее: 1. Стартовать его. 2. Останавливать 3. Конфигурировать 4. Получать его статус , а также статусы его "подмодулей" Модуль должен в зависимости от того как он сконфигурирован, САМ опрашивать источники данных (девайсы), вести статистику, БД и т.п. и. т.д.. А само приложение может получать нужные другим подсистемам данные от этого загруженного модуля посредством определенного API .. т.е приложению не нужны в принципе указатели на объекты в модуле... Ему нужны только АПИ!!! (я так пока предварительно решил) Судя по написанному здесь и немного далее, необходимости в использовании плагинов вообще нет, как я понимаю задачу. По данному описанию получается КП, который имеет постоянно загруженное ядро(со своим конфигом) и набор backend-ов с некоторой конфигурационной информацией. В соответствии с конфигом ядром запускает backend-ы. Хотя на самом деле здесь их лучше называть сервисы, т.к. ИМХО в данной ситуации лучше использовать сервисо-ориентированный подход. В соответствии с общей схемой сервисы предоставляют интерфейс управления ими: старт, стоп, перезагрузка конфига, получение статуса, пауза и т.д. Придумать можно много. Я сам реализовываю подобную штуку. Правда у меня нет реального времени. Для коммуникации между сервисами использую D-Bus, для управления и получения данных, а также извещений об изменении состояний так же D-Bus. Получается такое общее дерево объектов: Код: root Если по каким-то причинам такая схема не подходит, то... )))))) Ну, а если подходит, то могу дальше подробнее описать архитектуру... P.S. ИМХО, минус использования плагинов состоит в том, что если один из них рухнет, то пока всему приложению... Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 10:58 ну хорошо, например я послушаю ваш совет... и в приложении делаю так(примерно):
где-то в private класса MyDialog определен: Код: private: Код: void MyDialog::loadPlugins(const QString fileName) так код писать? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 11:15 2 Steven_Orko
дадада !! что то в этом роде! но эти "сервисы" должны быть отдельными библами... я не знаю как это назвать по научному, поэтому и путаю понятия "плагин", "модуль" и т.п. т.е сами сервисы подразумеваются пока как объект типа QThread !!! и чтобы в ядро их не сувать , мне надо как то придумать их сделать отдельно.. 1. т.е в приложении например выбираем в менюшке - типа "подключить модуть" 2. открывается окошко с предложением "выберите файл модуля (т.е библиотеку) 3. выбираем к примеру Modbus.dll (so) 4. жмем "подключить(загрузить) 5. чпок - типа читаем в какой нить метке статус - типа загружен успешно + в каком нить месте приложения в списке появляется имя этого подключенного модуля и краткая характеристика.. 6. при клике на название этого подключенного модуля - открывается другая форма, менюшка и т.п. в которой представлена возможность его конфигурирования и т.д. и.т.п. т.е. применительно к Модбас - это выбрать тип канала, контроллер, точку, регистры, БД, куда все будет сохраняться, параметры опроса выбранных контроллеров, каналов, точек и т.п. и. т.д. (см. спецификацию на протокол :) ) 7. после конфигурирования всего этого дела там же в окошке к примеру жмакаем "запустить" 8. и все... типа смотрим как оно работает , можем посмотреть какие получаем данные из сконфигуренных у-в и т.п. и т.д. У меня пока самая важная сейчас цель - понять, как мне подключать этот "модуль" к приложению!!! и это проблема!! :) но в принципе "легко" это можно сделать МОНОЛИТНЫМ! НО НЕ БУДУ! Цитировать Судя по написанному здесь и немного далее, необходимости в использовании плагинов вообще нет, как я понимаю задачу. ну а как обычно в приложениях такого рода это делают как подключают модули? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 11:24 Цитировать В соответствии с общей схемой сервисы предоставляют интерфейс управления ими: старт, стоп, перезагрузка конфига, получение статуса, пауза и т.д. Придумать можно много. ну а разве QT-шный подход с плагинами и их интерфейсами это не есть сие??? зачем они придумали интерфейсы, если можно все делать просто загружая динамическую библиотеку и беря из нее нужные ф-ции?? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Steven_Orko от Январь 15, 2009, 12:51 дадада !! что то в этом роде! но эти "сервисы" должны быть отдельными библами... я не знаю как это назвать по научному, поэтому и путаю понятия "плагин", "модуль" и т.п. т.е сами сервисы подразумеваются пока как объект типа QThread !!! и чтобы в ядро их не сувать , мне надо как то придумать их сделать отдельно.. Хм. Так я имел ввиду, что сервисы реализованы не в форме библиотеки, а в виде отдельного запускаемого бинарника, который при этом использует интерфейс (API) ядра. На форуме трудно полностью объяснить архитектуру. Я могу создать небольшой документ с описанием и переслать. Однако, для этого необходимо время. Цитировать В соответствии с общей схемой сервисы предоставляют интерфейс управления ими: старт, стоп, перезагрузка конфига, получение статуса, пауза и т.д. Придумать можно много. ну а разве QT-шный подход с плагинами и их интерфейсами это не есть сие??? зачем они придумали интерфейсы, если можно все делать просто загружая динамическую библиотеку и беря из нее нужные ф-ции?? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 15, 2009, 12:57 Цитировать зачем они придумали интерфейсы, если можно все делать просто загружая динамическую библиотеку и беря из нее нужные ф-ции?? Осознайте что пока вы так думаете - значит не разобрались в вопросе. Ставьте свои рассуждения под сомнение и примите на веру как вам говорят. Просветление прийдёт позже. Выше вы спрашивали так ли писать код. Ответ - да. Заметьте, что вашу ДЛЛ олицетворяет класс QPluginLoader, то-есть не QPlugin, а QPluginLoader - всего лишь загрузчик самого плагина. Как вы думаете, почему так? Подсказка: те кто придумывал названия классов - не идиоты. Внимание, спойлер! Он должен быть перевёрнутым, но такого тега я не нашёл. Такая схема сделана потому что ваш плагин может быть загружен не только из ДЛЛ. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Steven_Orko от Январь 15, 2009, 13:20 Ок. Решил написать сюда. Вот смотри.
Разбиваем весь програмный комплекс на две части: 1. Основная программа, так называемое ядро, и все, что с ним связано(настройки, библиотеки и т.д.). 2. Сервисы и все, что с ними связано (то же самое, что и в п.1, но для сервисов, если есть). Весь программный пакет включает в себя общую директорию, где хранятся все необходимые файлы: конфиги, бинарники, иконки и т.д. Директория примерно выглядит следующим образом: Код: root Такая структура моя, придумана чисто из субъективных сображений. Можешь свою создать. Просто дальнейшее описание буду приводить, основываясь на ней. Опишу немного общий процесс работы. Загружается основная программа. Читает настройки. Создает (в терминах D-Bus) шину сообщений. В соответствии с записями основного конфига программа запускает из директории services соответствующие сервисы. При необходимости управления сервисами можно создать приблизительно следующий интерфейс. Управление сервисами условно разделить на две группы: 1. Управление процессом сервиса 2. Управление конфигурацией сервиса Пункт 1. Управление процессом. Сервис можно добавлять, удалять в/из комплекса. Сервис можно автоматически стартовать, можно останавливать, получать статус работы. Все настройки для этого хранятся в основном конфиге комплекса. Там же и хранится весь (ПОЛНЫЙ!!!!) список установленных в комплекс процессов. Пункт 2. Управление конфигурацией сервиса. При запуске указанного пользователем сервиса должен происходить следующий процесс. Сервис проверяет свой конфиг, считывает настройки, если конфиг есть, или создает файл конфига со стандартными настройками. Далее подключается к шине сообщений, созданной ядром (основной програмой). Каким-либо образом инициализирует и запускает основной алгоритм, т.е. делает то, для чего он предназначен. При необходимости, в сервис можно добавить возможность рапортования об успешности запуска. Конфигурация сервиса возможна только из окна главной программы. При этом когда пользователь запускает механизм конфигурирования, основная программа смотрит список инсталированных сервисов, проверяет наличие соответствующих плагинов для создания окна конфигурирования в папке config->plugins. Если там плагин есть, то загружает из него объект окна и выводит на экран. Если нет, то считать сервис не настраиваемым. В плагине должны быть реализованы все функции по считыванию текущей конфигурации, сохранению новой, и, опять же если это надо, то извещению сервиса об изменении конфига. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 13:25 2 Dendy
хм.. но в моем случае тогда можно было бы обойтись и без QPluginLoader-a, т.е создать *.Dll в которой была бы аналогичная ф-я ModuleBase * create() ... и я с помощью QLibrary загружал бы бибриотеку, вызывал бы из нее эту ф-ю и она мне создавала бы объект типа ModuleBase и возвращала на него указатель и я бы из приложения его приводил к виду ModuleBase и работал бы с ним как хочу... ::) ? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 13:32 2 Steven_Orko
интересненько! :) а D-BUS он же "падучий" (у меня на PC по крайней мере раньше ошибки вылетали частенько с его участием) :) т.е применять его - ненадежно в принципе (ИМХО) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Steven_Orko от Январь 15, 2009, 13:50 а D-BUS он же "падучий" (у меня на PC по крайней мере раньше ошибки вылетали частенько с его участием) :) т.е применять его - ненадежно в принципе (ИМХО) Сколько я его не ломал, пока учился использовать, сам демон у меня ни разу не упал. Все зависит от версии, плюс я его сам немного подправил, помнится, и собрал. Т.е. получается, что это уже моя версия D-Bus. Но тебе не обязательно его использовать. Можно любую систему коммуникация между процессами, вплоть до самописного. Я просто привел пример архитектуры программного комплекса. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: Dendy от Январь 15, 2009, 14:04 хм.. но в моем случае тогда можно было бы обойтись и без QPluginLoader-a, т.е создать *.Dll в которой была бы аналогичная ф-я ModuleBase * create() ... и я с помощью QLibrary загружал бы бибриотеку, вызывал бы из нее эту ф-ю и она мне создавала бы объект типа ModuleBase и возвращала на него указатель и я бы из приложения его приводил к виду ModuleBase и работал бы с ним как хочу... А вот и не угадали. Разница между QLibrary и QPluginLoader описана в Ассистанте: Цитировать A Qt plugin is stored in a shared library (a DLL) and offers these benefits over shared libraries accessed using QLibrary:
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: ритт от Январь 15, 2009, 15:25 2 Steven_Orko интересненько! :) а D-BUS он же "падучий" (у меня на PC по крайней мере раньше ошибки вылетали частенько с его участием) :) т.е применять его - ненадежно в принципе (ИМХО) фу, как оскорбительно. и твоё "имхо" совсем неуместно. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 15:54 Цитировать фу, как оскорбительно. и твоё "имхо" совсем неуместно. :) в общем остановился пока на такой примерной реализации: interfaces.h Код: #ifndef INTERFACES_H myPlug.h Код: #ifndef MYPLUG_H myPlug.cpp Код: #include <QtGui> Название: Re: Загрузка классов из динамических библиотек??? Отправлено: -QT- от Январь 15, 2009, 17:24 Доброго времени суток Всем !
Свои 5 копеек. 1. Ядро с а) классом для обновления приложения (с GUI для администрирования) б) классом загрузки плагинов (с GUI для администрирования) в) классом распределения интерфейсов в зависимости от типа загруженного плагина г) классом распределения прав доступа к пунктам меню (с GUI для администрирования) 2. Плагины с реализацией функционала в новом потоке. (тогда при падении одного плагина все приложение не падает и не тормозит) Это как у меня сложилось в голове и в реализации. На выходе получаем (для примера) Товарно-кассовая система, драйвера для железа грузятся из плагинов ( можно одновременно иметь как несколько плагинов для одного типа оборудования так и для различного оборудования с выбором что использовать ); типы загружаемых плагинов разделены по группам функционирования ( если это драйверы оборудования то загрузить, установить сохраненные значения или по дефаулту, создать пункты меню для обеспечения администрирования, протестировать оборудование и ... выдать ответ -- "ОК") ( если это реализация бизнеслогики то выполняются необходимые действия для этого типа плагина ... ) То есть в зависимости от необходимости загружаем и используем или место кассира или место товароведа или место инспектора. и т.д. Даже даем спецификацию необходимую для загрузки модуля сторонним разработчикам (весь наш код при нас и никто его не видит :) ) а далее по готовности используем что нам сваяли. Мое мнение решение с применением плагинов дает более гибкий подход к реализации и использованию ПО. продукта. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 15, 2009, 19:25 2 -=QT=-
Цитировать 2. Плагины с реализацией функционала в новом потоке. (тогда при падении одного плагина все приложение не падает и не тормозит) а расскажите ка на пальцах принцип как вы это реализовали! а лучше в примерчиках :) имею ввиду потоки! да и вообще суть! :) Название: Re: Загрузка классов из динамических библиотек??? Отправлено: -QT- от Январь 16, 2009, 11:19 При реализации работы с плагинами сначала делаем рыбу:
Код
Код
Код
void QmyScanerPlugin::createThread(QObject* parent) Создание объекта сканера. На основе класса QmyScanerThread создает объект в отдельном потоке, который необходимо стыковать в сигнал-слот. Веё это выдрано из рабочего проекта. Код
Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 16, 2009, 11:53 2 -=QT=-
а реалирация ф-ци старта потока у вас вынесена в конструктор: QmyScanerThread(QObject * parent = 0); ??? т.е при создании потока - он автоматом у вас стартует? Название: Re: Загрузка классов из динамических библиотек??? Отправлено: -QT- от Январь 16, 2009, 12:23 угу.
Можно сделать как угодно - но сделано именно так. Это-же пример для тебя :), а собственная реализация приведет к нирване и повышенному благосостоянию. Название: Re: Загрузка классов из динамических библиотек??? Отправлено: kuzulis от Январь 16, 2009, 12:34 спс :)
я примерно так себе все и представлял... |