Russian Qt Forum

Qt => Qt-инструментарий => Тема начата: Гурман от Апрель 24, 2019, 01:30



Название: [РЕШЕНО] Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 01:30
Поскольку это явно проблема с плагином, пишу сюда.

Был у меня свой плагин для дизайнера, я их вообще наделал уже кучу, не было проблем пока. В плагине инклюдился файл со структурами, то есть struct а не class. У одной из них был конструктор без параметров, который инициализировал поля структуры. Всё было хорошо, плагин загружался в дизайнер и работал. Теперь мне потребовалось чтобы эта структура стала QObject. Я сделал её классом, наследовал QObject, включил в начало макрос Q_OBJECT, выполнил qmake, конструктор сделал public,  добавил ему параметр QObject* p=0, принял в нём этот параметр и передал в родительский QObject. Всё, как положено. Понаписал ещё всё что нужно было, пересобрал плагин, и бац... он перестал загружаться в дизайнер. В его списке загруженных плагинов написано что невозможно загрузить библиотеку из-за отсутствия символа _ZTV8myclassname - где myclassname имя этого класса.

В документации вроде бы нигде не сказано, что в плагине для дизайнера не могут быть несколько QObject - да и делал раньше с плагинам всё, что мне требовалось, всё было хорошо. _ZTV8myclassname - это вроде бы как конструктор. Но он вклассе есть. Долбаюсь полдня, пытаюсь понять что не так. Закомментировал в проблемном классе весь полезный код, все его поля. В конце концов добрался до следующего:

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

Проблема похоже специфичная для плагинов, может кто-то сталкивался или читал о похожем?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Igors от Апрель 24, 2019, 04:59
Можно поковырять Link Map, а главное - убедиться что класс экспортируемый, напр
Код:
#pragma GCC visibility push(default)

myclass {
..
};

#pragma GCC visibility pop
На разных платформах синтаксис может быть разным, можно попробовать Q_DECL_EXPORT


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: ssoft от Апрель 24, 2019, 08:23
Похоже, что дело под Windows, и что класс не экспортирован, поэтому и не линкуется. Q_DECL_EXPORT должен помочь.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 11:41
Похоже, что дело под Windows, и что класс не экспортирован, поэтому и не линкуется. Q_DECL_EXPORT должен помочь.
Linux Kubuntu. Зачем экспортировать класс, который используется только внутри плагина? Тем более... если вообще не используется. Ещё более не понятно, почему всё работало, пока класс был структурой.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 13:18
Не, нифига

class Q_DECL_EXPORT myclassname : public QObject

не помогает. Также как и #pragma GCC visibility push/pop

Всё та же фигня.  >:(


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: zhbr от Апрель 24, 2019, 14:24
а конструктор в public секции?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: zhbr от Апрель 24, 2019, 14:26
Ещё более не понятно, почему всё работало, пока класс был структурой.
Помоему нынче классы и структуры отличаются только тем, что по умолчанию все поля и методы в классах private, а в структурах public


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 14:46
а конструктор в public секции?
Ессно.

Помоему нынче классы и структуры отличаются только тем, что по умолчанию все поля и методы в классах private, а в структурах public
Дык отож! Но это может быть связано с наследованием от QObject - у структуры его не было.

Некогда время терять - надо соображать обходной путь, иначе собрал бы обрезанный проект и выложил. Может потом, когда устану.

Кстати, этот же класс нужен ещё в совсем другом плагине, попробовал собрать его с этим классом - та же фигня. Плагин тоже перестал загружаться в дизайнер.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Old от Апрель 24, 2019, 14:55
_ZTV это таблица виртуальных методов.
Попробуйте полностью пересобрать проект: удалить все файлы сборки, а дальше qmake && make.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 17:07
_ZTV это таблица виртуальных методов.
Попробуйте полностью пересобрать проект: удалить все файлы сборки, а дальше qmake && make.
Я это в первую очередь делал. И потом ещё несколько раз. В таблице виртуальных методов _ZTV8myclassname - конструктор.



Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Old от Апрель 24, 2019, 17:17
В таблице виртуальных методов _ZTV8myclassname - конструктор.
Нет, в C++ не бывает виртуальных конструкторов, его не может быть в VMT. Это символ самой таблицы. Почему она не добавляется в библиотеку - вопрос. А в объектном файле этого класса такой символ есть?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 17:43
А в объектном файле этого класса такой символ есть?

В дампе объектного модуля .o - да, есть. Причём именно в виде _ZTV8myclassname.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Old от Апрель 24, 2019, 17:45
В дампе объектного модуля .o - да, есть. Причём именно в виде _ZTV8myclassname.
Осталось понять почему линкер ее выбрасывает. :)
Попробуйте добавить виртуальный деструктор с пустым телом.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 19:25
Осталось понять почему линкер ее выбрасывает. :)
Попробуйте добавить виртуальный деструктор с пустым телом.

Нет, не помогает. Равно как и добавление dummy виртуальной функции, и переопределение виртуальных методов QObject. Мне кажется это косяк не линкера, а загрузчика плагинов Qt5, который используется в дизайнере. В Qt4 был другой загрузчик, я там делал гораздо сложнее вещи - и не было таких проблем.

Почти наверняка проблема с загрузчиком - в дампе .so плагина имя _ZTV8myclassname присутствует, то есть линкер его не выкинул.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Old от Апрель 24, 2019, 19:36
Мне кажется это косяк не линкера, а загрузчика плагинов Qt5, который используется в дизайнере.
Плагины это обычные динамические библиотеки и загружаются они системным загрузчиком ld, это его ошибка о неизвестном символе.

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


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 19:45
Плагины это обычные динамические библиотеки и загружаются они системным загрузчиком ld, это его ошибка о неизвестном символе.
Не знаю как в Qt5, но в Qt4 к символам внутри библиотеки-плагина я обращался вручную, то есть явно вызывал загрузку библиотеки из своего каталога, и вызывал для их инициализации экспортированные из них методы. У меня приложение состояло из небольшого загрузчика, который больше ничего не умел, а всё остальное - плагины. При этом всё это одинаково работало в Windows и Linux.

А не может быть дублирования символов? Не может такого быть, что в плагинах загруженных ранее есть класс с таким же именем?
Вроде нет. Не должно. Тогда ошибка должна быть другой - дублирование.

ЗЫ: Проследил - нет, в других плагинах это имя не используется. Вообще - почему именно когда появляется конструктор, то всё ломается? И какое отношение конструктор может иметь к таблице виртуальных методов?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Old от Апрель 24, 2019, 20:32
Тогда ошибка должна быть другой - дублирование.
Нет. Будет использоваться первый известный загрузчику символ. На этом принципе работают всякие инжекторы, которые заменяют нужные функции своими, загружая свою разделяемую библиотеку первой.

ЗЫ: Проследил - нет, в других плагинах это имя не используется. Вообще - почему именно когда появляется конструктор, то всё ломается? И какое отношение конструктор может иметь к таблице виртуальных методов?
Я так понимаю, что вы загружаете сразу несколько своих плагинов. А попробуйте оставить для загрузки только один этот.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 20:33
Я так понимаю, что вы загружаете сразу несколько своих плагинов. А попробуйте оставить для загрузки только один этот.

Не имеет значения. Вообще дублирование имён в плагинах никак не влияет - у меня их куча, и в них навалом дублирующихся имён. Всё прекрасно работает. Загрузчик их грузит последовательно, резолвит ссылки, и когда грузит следующий, загруженные уже не мешают. Это же плагины виджетов дизайнера, там невозможно без дублирования имён обойтись.

Оппа... Убираю макрос Q_OBJECT в начале класса - плагин грузится, со всеми конструкторами, сигналами, слотами и прочим. То есть, целиком, без каких-то других сокращений. Возвращаю - не грузится.

Сейчас собрал ещё один аналогичный плагин с другим функционалом, но он тоже инклюдит этот класс. Тоже без Q_OBJECT в этом классе. И дизайнер загрузил оба эти плагина. Но мне необходим Q_OBJECT - сигналы и слоты нужны.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Авварон от Апрель 24, 2019, 22:46

Оппа... Убираю макрос Q_OBJECT в начале класса - плагин грузится, со всеми конструкторами, сигналами, слотами и прочим. То есть, целиком, без каких-то других сокращений. Возвращаю - не грузится.


moc-то отработал? файл подцепился? что будет, если заинклюдить мок в цпп?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 23:10
moc-то отработал? файл подцепился? что будет, если заинклюдить мок в цпп?

Что это за странные вопросы? Класс с Q_OBJECT, signals:, public slots:, emit... компилируется и создаётся объектный модуль.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Авварон от Апрель 24, 2019, 23:15
но-но, мок делает отдельный цпп с отдельным .о файлом. Он есть?


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 23:19
но-но, мок делает отдельный цпп с отдельным .о файлом. Он есть?
Стоп, а как moc может не отработать? Исходник указан в проекте сразу следом за исходниками самого плагина.
И как этот класс может компилироваться, если в нём есть ключевые слова moc, не известные GCC?
Вообще-то объектника с именем, начинающемся с moc_ для исходника с этим классом нет.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Гурман от Апрель 24, 2019, 23:38
БЛИИИНННН.... Слов нет, одни буквы... В проекте в секции

HEADERS =

отсутствовал заголовочный файл в котором описан этот класс.  >:( Когда структуру на класс поменял, не добавил его. Структуре оно как бы пофик было, она не изменялась давно, без этого всё работало - файл инклюдился по маршруту в INCLUDEPATH =.

И, блин вся эта двоичная троллевская мутота, скотина МОЛЧА всё жуёт, никаких сообщений, даже варнингов, делает плагин на выходе - и .....

Тфу. Заработало.


Название: Re: Непонятная проблема с плагином для QtDesigner
Отправлено: Авварон от Апрель 24, 2019, 23:39
кумейкопроблемы ;)