Реализация системы плагинов в C или C ++ - PullRequest
30 голосов
/ 02 апреля 2009

Какие у вас советы по внедрению системы стилей плагинов?

Ответы [ 11 ]

30 голосов
/ 02 апреля 2009

В C (и я думаю, что C ++ тоже, хотя я сам этого не делал), это обычно делается с использованием динамически загружаемых модулей. API для таких приложений зависит от платформы.

В POSIX (Linux) вы используете семейство функций <a href="http://linux.die.net/man/3/dlopen" rel="noreferrer">dlopen()</a>. По сути, вы создаете свой плагин отдельно, затем загружаете его во время выполнения, ищите его символы по имени и затем можете вызывать их.

Для Win32 существует <a href="http://msdn.microsoft.com/en-us/library/ms684175%28VS.85%29.aspx" rel="noreferrer">LoadLibrary()</a>, который делает что-то очень похожее, вы встраиваете свой код в DLL.

Для удобной обертки, которая делает все это простым и прозрачным, ознакомьтесь с GLib's GModule API.

11 голосов
/ 03 апреля 2013

Лучшая платформа и языковой совет, который я могу дать, это:

Создайте свое приложение на основе плагина SDK.

ИМО, плагин SDK не должен быть запоздалой мыслью. Если вы разрабатываете свое приложение как пустую оболочку, которая загружает плагины, тогда основные функции реализованы в вашем собственном SDK, вы получите следующие преимущества:

  • Высокая модульность компонентов и четкое разделение целей (это как бы заставляет вашу архитектуру быть хорошей)
  • Это заставляет ваш SDK быть действительно хорошим
  • Позволяет сторонним разработчикам создавать чрезвычайно мощные функции уровня ядра
  • Новые разработчики / наемники могут легко начать работу над новой важной функцией, не касаясь основного приложения - они могут выполнять всю свою работу в плагине (что не позволяет им испортить что-либо еще)

В C / C ++ вы, вероятно, используете библиотеки динамических ссылок и либо указатели функций (C), либо интерфейсы (классы, состоящие исключительно из чисто виртуальных методов для C ++). Однако даже если вы используете Javascript, я все равно рекомендую вышеупомянутую архитектуру.

11 голосов
/ 02 апреля 2009

В период времени '92 / '93 я работал над архитектурой плагинов для Aldus PageMaker, которая была написана на C ++. PageMaker был построен на платформе ООП C ++ под названием VAMP, что способствовало его переносимости между Mac OS и Windows.

Итак, мы попытались использовать возможности C ++ для построения архитектуры плагинов. Это оказалось очень проблематичным для классов C ++ из-за так называемой проблемы хрупкого базового класса. Я приступил к написанию статьи, которая была опубликована в журналах и которую я представил на OOPSLA '93 на семинаре по анализу. Я также связался с Бьярном Страуструпом на конференции Usenix в Портленде и продолжал вести с ним диалог в течение нескольких месяцев, где он отстаивал проблему решения проблемы хрупкого базового класса от моего имени. (Увы, в то время другие вопросы считались более важными.)

Microsoft представила систему COM / DCOM и для этой платформы, которая рассматривалась как жизнеспособное решение проблемы. C ++ может использоваться в качестве языка реализации COM через абстрактные классы, используемые для определения интерфейсов COM.

Однако в наши дни разработчики избегают использования COM / DCOM.

В отличие от этого, NeXT разработал архитектуру плагинов с использованием Objective C в начале 90-х годов в рамках NeXT Step. Сегодня он живёт в Mac OS X на компьютерах Apple и на таких важных платформах, как iPhone.

Я представляю, что Objective C позволил решить проблему с плагином превосходным образом.

Лично я считаю, что хрупкая проблема базового класса в C ++ является ее самой фатальной ошибкой.

Если бы строили архитектуру плагинов с семейством языков на основе C, это делалось бы с использованием Objective C.

5 голосов
/ 04 марта 2012

Qt предоставляет QPluginLoader: http://qt -project.org / док / кварта-4,8 / qpluginloader.html

Если вам нужно / нужно более детализированное управление, Qt также предоставляет средство для загрузки библиотек на лету с QLibrary: http://qt -project.org / док / кварта-4,8 / qlibrary.html

Еще лучше, они переносимы между платформами.

5 голосов
/ 04 апреля 2009

Возможно, это не то, что вы ищете, но вы можете встроить язык сценариев в свое приложение, например Lua. Lua был разработан для встраивания в другие программы и использования в качестве языка сценариев для написания плагинов. Я считаю, что довольно легко добавить интерпретатор Lua в вашу программу, хотя я не знаю Lua, поэтому я не могу ручаться за то, насколько эффективным будет решение. Другие с большим опытом работы с Lua, пожалуйста, добавьте комментарии о вашем опыте встраивания Lua в другое приложение.

Это, конечно, будет означать, что ваши плагины должны быть написаны на Lua. Если вам не нравится Lua, тогда стандартные интерпретаторы Perl, Python и Ruby де-факто все написаны на C и могут быть встроены в C-программу. Мне известен ряд программ, которые используют эти языки в качестве расширений языка сценариев.

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

3 голосов
/ 04 апреля 2009

Лучше всего использовать такую ​​среду, как ACE (http://www.cs.wustl.edu/~schmidt/ACE.html)), которая защищает вас (насколько это возможно) от кода, специфичного для платформы.

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

Для более высокого уровня абстракции посмотрите CIAO (http://www.cs.wustl.edu/~schmidt/CIAO.html) реализация C ++ с открытым исходным кодом в компонентной модели CORBA.

2 голосов
/ 07 октября 2013

Я написал статью о том, как реализовать систему плагинов с использованием динамически подключаемых библиотек. Статья написана с точки зрения программиста Windows, но метод может быть применен к среде типа Linux / Unix.

Статью можно найти здесь: http://3dgep.com/?p=1759

Суть в том, что вы должны создать «общую» DLL, которая неявно связана как основным приложением (основным приложением), так и реализациями плагина. Затем плагины могут быть явно связаны и загружаться динамически во время выполнения основным приложением.

В статье также показано, как можно безопасно обмениваться статическим (одноэлементным) экземпляром класса между несколькими библиотеками DLL с помощью «общей» библиотеки DLL.

В статье также показано, как можно экспортировать функцию или переменные "C" из DLL и использовать экспортированные функции в приложении во время выполнения.

2 голосов
/ 04 марта 2012

Посмотрите на Poco Class Loader , это может быть вам интересно.

1 голос
/ 05 июня 2009

Этот подкаст о архитектурах плагинов также может быть интересен.

0 голосов
/ 03 апреля 2013

Я написал библиотеку плагинов Pugg , которая загружает классы C ++ из DLL-файлов, и вот логика, которую я использовал:

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

Функция C регистрирует один или несколько заводских классов, называемых «Драйвер». Каждый класс Driver связан со строкой. Когда основное приложение хочет создать класс, оно собирает связанный класс фабрики, используя связанную строку. Я также внедрил систему проверки версий, чтобы не загружать старые плагины.

Загрузка Dll выполняется с использованием функций LoadLibraryA и GetProcAddress (Pugg в настоящее время работает на окнах).

Стоит отметить, что основное приложение и библиотеки DLL должны быть скомпилированы с использованием одного и того же компилятора и с одинаковыми параметрами компиляции (режимы выпуска / отладки, настройки оптимизации, версии stl и т. Д.). В противном случае могут возникнуть проблемы с отображением классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...