|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
11.01.2010, 14:39 | #1 |
Старожил
Регистрация: 06.08.2009
Сообщений: 2,992
|
Программа с динамически подключаемыми библиотеками (плагинами)
Недавно пришлось освоить такую технологию, теперь хочу поделиться с форумчанами, кому надо.
Я попробовал несколько вариантов - интерфейс плагина в отдельной DLL, в отдельном .cs, или встроенный в .exe; остановился на последнем. 1) Создаём проект основной программы (Windows Forms или Console Application), в нём добавляем файл с интерфейсом классов плагинов (Project -> Add New Item -> Interface). Интерфейс - это класс, в котором объявлены прототипы методов. Если класс наследуется от интерфейса, он обязан переопределить все его методы, см. DSPluginInterface.cs. 2) В тот же solution добавляем Class Library Project, в References добавляем ссылку на проект основной программы, содержащей интерфейс. Наследуем класс плагина от интерфейса. См. DSPluginTxtIO.cs. 3) Пишем основную программу, которая ищет *.dll, а в них - объекты, унаследованные от интерфейса (см. Program.cs). Конкретную реализацию смотрите в проектах, далее опишу только их настройку. Тут такая хитрость: во время компиляции проект плагина жёстко зависит от основной программы. В то же время, когда мы жмём F5, мы хотим, чтобы перед запуском все плагины автоматически скомпилировались и скопировались в папку основной программы. Обычно это достигается установкой зависимостей (Project Dependencies), но в нашем случае это приведёт к циклическим зависимостям. На самом деле эти зависимости возникают в разное время, но Visual Studio этого не знает, и выдаёт ошибку. Поэтому мы прибегнем к полуавтоматическому копированию файла *.dll в папку Debug или Release. Это достигается настройкой проекта плагина (обратите внимание - не основной программы): Project Properties -> Build Events -> Post-build... нужно написать так: copy "$(TargetPath)" "$(SolutionDir)DSPluginsApplication \$(OutDir)" при этом, конечно, заменив DSPluginsApplication на имя проекта вашей основной программы. Обратите внимание: эта строка не зависит от типа компиляции (Debug или Release), это необходимо, так как у разных типов компиляции нельзя задать разные настройки. При нажатии F5 происходит следующее: 1) компилируется основная программа 2) с использованием первого скомпилированного проекта компилируется плагин (зависимость A->B) 3) плагин копируется к основной программе 4) программа запускается с плагином у себя (зависимость B->A) Стороннему разработчику, чтобы написать плагин, нужно скопировать программу (exe) себе в проект, и указать этот файл в References. При этом программист может написать в своём проекте, скажем, имя интерфейса, нажать Go To Definition, и он увидит исходный код интерфейса - это что-то вроде дизассемблирования. Далее - исходники. В моём примере плагин читает из input.txt, и пишет в output.txt. Программа ищет нужные классы во всех DLL, подключает, предлагает выбрать, и запускает функции Read() и Write() (см. интерфейс). В конце поста прикреплён весь проект. Интерфейс плагинов, DSPluginInterface.cs: Код:
Сам плагин, DSPluginTxtIO.cs: Код:
Последний раз редактировалось ds.Dante; 11.01.2010 в 14:49. |
11.01.2010, 14:41 | #2 |
Старожил
Регистрация: 06.08.2009
Сообщений: 2,992
|
Основная программа, Program.cs:
Код:
|
12.01.2010, 22:13 | #3 |
Пользователь
Регистрация: 14.10.2009
Сообщений: 70
|
Спасибо. Мне тоже скоро надо этим заняться (опыта нету), буду изучать.
|
18.01.2010, 00:40 | #4 |
Форумчанин Подтвердите свой е-майл
Регистрация: 20.11.2007
Сообщений: 500
|
Как раз хотел задать вопрос по этой теме, а вы уже на всё ответили!
Но вот что ещё интересует: можно же интерфейс для плагинов скомпилировать в отдельную библиотеку и подключать к проекту плагинов её, а не сам исполняемый файл?? |
18.01.2010, 10:45 | #5 |
Старожил
Регистрация: 06.08.2009
Сообщений: 2,992
|
Можно. Для этого нужно создать проект Class Library, состоящий из одного интерфейса. Полученную DLL подключать к основному проекту и к плагинам.
Плюс такого подхода - никаких циклических зависимостей, проекты зависят только от этой DLL. Минус - лишний файл в программе. Кто-нибудь скопирует прогу, а у него - бах! - ошибка: не найден файл DSPluginInterface.dll. |
13.04.2010, 18:02 | #6 |
Android Developer
Старожил Подтвердите свой е-майл
Регистрация: 19.02.2007
Сообщений: 3,708
|
Благодарю за пример. Самому скоро придется реализовывать, а пока время тратить на разборку не хотелось. Спасибо еще раз.
Как дополнение, или уточнение, это Windows Forms или WPF ? Меня собственно интересует WPF, т.е. если интерфейс (программа) UserControl в .dll файле, то основное приложение (.exe) может грузить и как я понимаю, брать этот UserControl и обращаться с ним как с таким же UserControl если бы он был в самой программе (.exe) ? Такой заковыристый вопрос, просто если знаете то подтвердите мою теорию, если нет, то ладно, придет время сам разберусь. |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Работа с библиотеками типов(TLB) в С++ | MadBoxer | Общие вопросы C/C++ | 1 | 14.05.2009 16:59 |
работа с библиотеками | kuzmich | Общие вопросы Delphi | 2 | 25.02.2009 19:39 |
Mozilla Firefox 3.0.4 Глюки с плагинами? | iankov | Софт | 0 | 09.01.2009 17:44 |
проблемма с подключаемыми файлами | ratibor32 | Общие вопросы C/C++ | 4 | 18.01.2008 11:36 |