Подтвердить что ты не робот

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Существуют также более тяжелые решения, такие как CORBA...

Ответ 3

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

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

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


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

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