Russian Qt Forum

Qt => Вопросы новичков => Тема начата: joffadark от Февраль 08, 2015, 13:59



Название: QtPluginLoader в static-приложении
Отправлено: joffadark от Февраль 08, 2015, 13:59
Здравствуйте, уважаемые форумчане.

Использую Qt 5.3.1, который скомпилировал из исходного кода статически.
Под операционкой Linux Ubuntu 12.04.

Соответственно, мое приложение на выходе получается тоже статически слинкованным.

Теперь возникла задача реализовать динамическую загрузку плагинов приложения
при помощи QtPluginLoader.
Сколько не пытался, QtPluginLoader всегда возвращает "Unknow error". Даже примеры самого
Qt (echoplugin пробовал).

Вопрос: возможно ли загружать из программы, собранной статически, собственные плагины?
Если возможно, то может быть плагины нужно собирать как-то по-особому?


Название: Re: QtPluginLoader в static-приложении
Отправлено: Igors от Февраль 08, 2015, 15:19
Вопрос: возможно ли загружать из программы, собранной статически, собственные плагины?
Если возможно, то может быть плагины нужно собирать как-то по-особому?
Тоже не раз задавал этот вопрос, ответа или не получал или "нет" (но как-то не очень охотно :)). Очевидно что возни больше чем достаточно, и проще/лучше линковать дынамычно, без затей.

Но я не могу доказать что "нельзя". Что принципиально мешает плагину дергать нужные ф-ции/классы из самого приложения (вместо dll)? ведь и в приложении они экспортируются. Во всяком случае это интересно.


Название: Re: QtPluginLoader в static-приложении
Отправлено: Bepec от Февраль 08, 2015, 16:59
Вот когда у кого то желание разобраться победит над ленью, то он возьмёт дебагер и пройдёт по шажкам в тёмные, но упорядоченные дебри исходников Qt и даст вам ответ :)


Название: Re: QtPluginLoader в static-приложении
Отправлено: joffadark от Февраль 08, 2015, 17:11
Вопрос: возможно ли загружать из программы, собранной статически, собственные плагины?
Если возможно, то может быть плагины нужно собирать как-то по-особому?
Тоже не раз задавал этот вопрос, ответа или не получал или "нет" (но как-то не очень охотно :)). Очевидно что возни больше чем достаточно, и проще/лучше линковать дынамычно, без затей.

Но я не могу доказать что "нельзя". Что принципиально мешает плагину дергать нужные ф-ции/классы из самого приложения (вместо dll)? ведь и в приложении они экспортируются. Во всяком случае это интересно.

Но ведь для Linux-пользователей неудобно предоставлять работающее "stand-alone" приложение, если собирать его с динамической линковкой...:(
Половину интернета нужно за собой таскать или пользователю скачивать.

А модульность своему приложению тоже очень хочется придать: удобство обновления тех или иных модулей, более удобная доработка и прочие прелести.

В общем, беда.  ???


Название: Re: QtPluginLoader в static-приложении
Отправлено: xokc от Февраль 08, 2015, 22:40
Вопрос: возможно ли загружать из программы, собранной статически, собственные плагины?
Если возможно, то может быть плагины нужно собирать как-то по-особому?
Ответ - возможно, но статические плагины при этом должны быть... статически слинкованы с самой программой.


Название: Re: QtPluginLoader в static-приложении
Отправлено: xokc от Февраль 08, 2015, 22:44
Что принципиально мешает плагину дергать нужные ф-ции/классы из самого приложения (вместо dll)? ведь и в приложении они экспортируются.
"Экспортируются в приложении"? Не очень понимаю о чём тут речь. Предополагается, что статитчески слинкованные с основным приложением dll (например, QtCore.dll) должны быть доступны для использования внешним плагином?


Название: Re: QtPluginLoader в static-приложении
Отправлено: vbv от Февраль 09, 2015, 01:57
Точного ответа не знаю но вставлю свои 5 копеек.
Плагин - это библиотека.
Если собрано статическое приложение - в нем возможно отсутствует часть отвечающая за загрузку библиотек. А если плагин - библиотека.......

С другой стороны может быть и возможно но тут, как мне кажется, нужно смотреть в сторону параметров сборки самого QT.


Название: Re: QtPluginLoader в static-приложении
Отправлено: Igors от Февраль 09, 2015, 11:13
Ответ - возможно, но статические плагины при этом должны быть... статически слинкованы с самой программой.
Ну это не то что требуется.

"Экспортируются в приложении"? Не очень понимаю о чём тут речь. Предополагается, что статитчески слинкованные с основным приложением dll (например, QtCore.dll) должны быть доступны для использования внешним плагином?
Нет. Пример
Код
C++ (Qt)
class Q_CORE_EXPORT QString
{
 
Изменив/настроив Q_CORE_EXPORT мы можем добиться чтобы оно означало "dllexport" (в терминах Вындоуз). После компиляции приложения имеем lib файл в котором класс экспортируется, доступен извне. Линкуем плагин с этой либой. Не вижу почему это не должно работать.


Название: Re: QtPluginLoader в static-приложении
Отправлено: xokc от Февраль 09, 2015, 13:46
Ответ - возможно, но статические плагины при этом должны быть... статически слинкованы с самой программой.
Ну это не то что требуется.
Я бы сформулировал иначе :) Это требуется то, что не может быть реализовано средствами плагинной системы Qt. О чем недвусмысленно говорится в документации: Static Plugins: Plugins can be linked statically into your application. (http://doc.qt.io/qt-5/plugins-howto.html#static-plugins)

После компиляции приложения имеем lib файл в котором класс экспортируется, доступен извне. Линкуем плагин с этой либой. Не вижу почему это не должно работать.
В этой либе прописано конкретно из какой именно (в терминах Windows) DLL (а не EXE!) можно будет подгрузить код на этапе выполнения. Теоретически допускаю, что можно было бы сделать так, чтобы импортировать код и данные и из исполняемого файла (непонятно только зачем?), но так не сделано (по крайней мере в Windows) - поэтому и искать реализацию подобных вещей на уровне Qt бессмысленно.


Название: Re: QtPluginLoader в static-приложении
Отправлено: Igors от Февраль 09, 2015, 14:45
В этой либе прописано конкретно из какой именно (в терминах Windows) DLL (а не EXE!) можно будет подгрузить код на этапе выполнения.
Если Qt либы слинкованы статычно, то никаких ссылок на Qt dll нет, код того же QString принадлежит exe файлу, так же как если бы в проект был включен QString.cpp


Название: Re: QtPluginLoader в static-приложении
Отправлено: xokc от Февраль 10, 2015, 12:09
Igors, я Вас не очень понимаю. Давайте по порядку. Имеем Windows проект, состоящий из:
1. staic.lib (именно static lib, не dll - для Windows это разные типы lib!)
2. host.exe
3. plugin.dll
В static.lib имеем класс Shared, объявленный как Q_DECL_EXPORT, в host.exe и в plugin.dll используем этот класс, как Q_DECL_IMPORT. В итоге после линковки host.exe + static.lib и plugin.dll + static.lib имеем два разных экземпляра реализации Shared, по одному в exe и dll. О каком общем Shared может идти речь в данном случае?
Для Windows термин "слинкован статычно" неприминим. Для "статической линковки" в Вашей терминологии используется lib, содержащий полный используемый код модуля, для "динамической" - lib, содержащий только ссылки для вызова соответсвтвующего кода из совершенно конкретной dll.


Название: Re: QtPluginLoader в static-приложении
Отправлено: Igors от Февраль 10, 2015, 13:36
В static.lib имеем класс Shared, объявленный как Q_DECL_EXPORT, в host.exe и в plugin.dll используем этот класс, как Q_DECL_IMPORT. В итоге после линковки host.exe + static.lib и plugin.dll + static.lib имеем два разных экземпляра реализации Shared, по одному в exe и dll. О каком общем Shared может идти речь в данном случае?
Я имею ввиду: host.exe + static.lib и plugin.dll + MyApp.lib

Вот мы компилим статическую Qt5Core.lib. Мы можем сделать Q_DECL_EXPORT/IMPORT вообще пустыми, для статики они не требуются. Теперь мы компилим с Q_DECL_EXPORT как dllexport. В итоге получаем приложение слинкованное статически, но у которого есть export классов Qt что записан в MyApp.lib. Теперь мы подсовываем этот MyApp.lib плагину, он хочет грузить MyApp.exe - но он уже загружен т.к. плагин зовется из него.

Тут возможна такая неприятность: а не выкинет ли линкер неиспользуемые классы/методы, а плагину они могут понадобиться. Ну это уже детали. А так не вижу никакой ошибки. Найду время - попробую