Дизайн API плагина

Итак, у меня есть приложение, в значительной степени основанное на QT API, использующем систему QPlugin. Его довольно просто использовать, вы определяете класс, который наследуется от интерфейса, и когда плагин загружается, вы получаете экземпляр этого класса. В конце концов, это будет dlopen / dlsym или LoadLibrary / GetProcAddress, в зависимости от того, что подходит для ОС. У меня тут проблем нет, все работает как положено.

Итак, к вопросу. Существует много функциональности, которая включает в себя плагин, который должен ссылаться на данные / функции, предоставляемые основным приложением. Например, у моего приложения есть графический интерфейс, поэтому в моем приложении есть функция «plugin::v1::gui», которая возвращает QWidget *. Если я хочу, чтобы плагин мог добавлять что-то в мой пользовательский интерфейс или даже делать его диалог дочерним по отношению к моему пользовательскому интерфейсу, ему понадобится указатель на него.

Я начал разработку на Linux и быстро обнаружил, что по умолчанию загрузчик не заполняет неразрешенные символы в общих объектах с символами из приложения, загружающего его. Нет проблем, легко исправить. добавляю "-rdynamic" к моим флагам и двигаюсь дальше. Вещь работает хорошо.

Теперь я обнаружил, что в Windows, похоже, нет эквивалента :(. Итак, какое решение является хорошим?

Пока что лучшее, что я придумал, - это структура, которую я заполняю в своем основном приложении, которая имеет указатели на каждый объект / функцию, о которых может заботиться плагин. Затем передайте это функции плагина «init()», и теперь у нее есть правильные указатели на все, но это раздражающее решение, поскольку теперь мне приходится вносить изменения в нескольких местах, когда я что-то добавляю.

Есть ли лучшее решение? Как сообщество SO с этим справилось?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
3 033
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Создайте объект реестра, который передается плагину в функции инициализации, которая содержит словарь открытых компонентов. Затем разрешите плагину запрашивать указатель на компоненты по строковому имени или другому идентификатору из этого реестра. Он жертвует безопасностью типов во время компиляции ради стабильного интерфейса.

Есть и более тяжелые решения вроде CORBA ...

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

Evan Teran 09.12.2008 07:01

Я не могу представить другого решения проблемы. что ты думаешь об Эване?

Johannes Schaub - litb 09.12.2008 07:41

К сожалению, пока я не нашел ничего действительно лучшего. Было бы неплохо придерживаться Linux -rdynamic. Я начал преобразовывать API своего плагина в переданную структуру, и это требует времени В самом деле, чтобы разобраться.

Evan Teran 09.12.2008 08:59

Вы сделали это относительно хорошо. Вспомогательные классы часто являются чистым способом (только) ВСТАВКИ новой функциональности. Если вы недавно разрабатываете свое программное обеспечение, вы должны упомянуть, что не каждый плагин должен иметь доступ к вашей административной структуре. Так что различия в дизайне плагинов должны быть.

Одна возможность: Создайте несколько абстрактных классов, от которых вы наследуете, которые имеют функциональные возможности для установки требуемых указателей на виджеты или около того.

Другая возможность: Расширьте свои основные (родительские) классы функциями getParent (). GetMainWidget (), getParent (). GetConfigWidget () ....


Если речь идет только о динамической загрузке пользовательских интерфейсов из вашего UI-плагина без использования указателей, вы можете сделать это, как описано на этой странице: http://dolzhenko.blogspot.com/2008/10/qt4-dynamic-loading-ui-from-other-ui_07.html

Это делается с помощью ui-файлов, к которым вы можете получить доступ через свои основные файлы конфигурации или что-то еще.

Ответ принят как подходящий

Создайте набор интерфейсов для основных объектов взаимодействия, которые будут предоставляться вашим приложением, и создайте их в собственной библиотеке lib / dll и при необходимости реализуйте эти интерфейсы в классах вашего приложения. Библиотека также должна включать интерфейс плагина с, возможно, просто методом «инициализации», который будет реализовывать объект плагина.

Приложение и плагин, очевидно, будут связываться с этой DLL, и как только плагин будет загружен приложением, приложение должно вызвать метод инициализации плагина, который будет иметь параметры для принятия любых объектов, необходимых для управления приложением.

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

Вот хорошая статья, в которой подробно объясняется, как создавать плагины таким образом: nuclex.org/articles/…

joshperry 11.01.2009 23:21

Другие вопросы по теме