Page 1 of 1

Простой плагин (draft)

Posted: Mon 01 Apr, 2013 08:20
by Skirda
Вводная

Что такое "плагины"? Как говорит Википедия - это "независимо компилируемый программный модуль, динамически подключаемый к основной программе и предназначенный для расширения и/или использования её возможностей". Применительно к Far Manager так оно и есть - множество полезных функций (обзор сети, временная панель, "гляделка" процессов, просмотр изображений и т.п.) выполнено как плагины.

Почему именно "плагины", а не прямая компиляция функционала в ядро Far Manager? Здесь все просто и вытекает из определения термина "плагин" - я хочу вот эту фишку в редакторе, а соседу она будет лишней. Ок, я ставлю плагин, добавляющий эту фишку, а сосед пусть "мучается" - при этом ему хорошо, я доволен и вместе мы не перегружаем исходный код Far Manager "ненужными" функциями.

А что делать, если этой самой функции нигде нет? Здесь три пути:
  1. написать плагин самому
  2. найти (и убедить в нужности функционала) того, кто нам напишет такой плагин
  3. смириться (или становимся программистом и далее путь 1)
Наш путь первый, о чем, собственно, статья. Не будем отступать от традиций и в качестве примера возьмем плагин "helloworld", входящий в инсталляцию Far Manager.

Собираем материал.

Итак, цель есть - простой и понятный плагин, вызов которого приветствует пользователя фразой "Здравствуй, Мир!". Остались вопросы:
  1. Какой минимальный набор функций, чтобы Far Manager понял, что наша dll - плагин?
  2. Интерфейс может быть на другом языке, отличным от начертания "Здравствуй, Мир!". Как сделать мультиязычный интерфейс?
  3. Каким образом Far Manager вообще работает с плагинами?
  4. Какие файлы входят в проект?
Как Far Manager работает с плагинами?

Прежде чем двигаться дальше, посмотрим, что делает Far Manager от момента запуска до приема команд от пользователя.
  1. Пользователь запускает Far Manager.
  2. Far Manager настраивает свое окружение (инициализация глобальных переменных, конфигурационных баз, панелей и прочих объектов интерфейса).
  3. Загружает плагины.
  4. Загружает макросы.
  5. Запускает основной цикл обработки и показывает панели.
Подробнее рассмотрим загрузку плагинов.
Для известных путей происходит сканирование файловой структуры на наличие файлов "*.dll".
Очередной найденный dll-модуль проверятся на предмет принадлежности в текущей OS, на наличие предопределенных экспортируемых функций (пока GetGlobalInfoW).
.
.
.

Минимальный набор функций.

Весь набор экспортируемых функций, которые понимает Far Manager и ожидает от плагина, можно подсмотреть в конце файла plugin.hpp. Но чтобы плагин "взлетел", понадобится следующий минимальный набор экспортируемых функций:
  • GetGlobalInfoW - Основная информация о плагине - автор, версия, GUID плагина, описание плагина, минимальная версия Far Manager. Функция вызывается один раз сразу после загрузки DLL-модуля в память.
  • SetStartupInfoW - Вызывается один раз, сразу после вызова функции GetGlobalInfoW. Far Manager передаёт плагину информацию, необходимую для дальнейшей работы (указатели на сервисные и некоторые полезные внутренние функции Far Manager).
  • GetPluginInfoW - Far Manager вызывает эту функцию для получения дополнительной информации о плагине (из какого места можно вызвать плагин, префикс(ы), строки для разных меню вызова).
  • OpenW - Far Manager вызывает OpenW, когда пользователь желает воспользоваться функциями плагина. Здесь мы реализовываем основной функционал.
Если плагин позволяет изменять некоторые свои настройки, то понадобится экспортируемая функция ConfigureW. Но в нашем простом плагине настраивать ничего не будем.

Состав проекта.
В проекте будут следующие файлы:
  • README.TXT - Описание плагина. Что, зачем и почему. Пользователь всегда хочет знать подробности.
  • changelog - Что менялось в проекте от версии к версии. Файл опциональный, но полезный.
  • guid.hpp - GUID`ы плагина, меню, диалогов.
  • HelloWorld.cpp - "Ядро" системы. Т.к. описываемый плагин простой, то весь код разместим в одном файле.
  • HelloWorld.hpp - Локальные функции и определения проекта. Опционально, если весь код в одном файле.
  • HelloWorld.rc - Ресурсы. Версия dll-модуля
  • HelloWorld*.hlf - Файлы справки на разных языках. Опционально, но полезно - пользователю можно сказать "жми F1 и читай". Можно повторить содержимое README.TXT.
  • HelloWorld*.lng - Языковые ресурсы - строки, которые плагин показывает пользователю (в меню, диалогах, и пр.).
  • HelloWorldLng.hpp - Содержит константы, определяющие строковые ресурсы в lng-файлах.
  • HelloWorldW.def - Показывает сборщику, какие функции экспортирует dll-модуль.
  • makefile - Файл, содержащий правила сборки плагина (правила, которые понимает команда make.exe и аналогичные).
  • version.hpp - Содержит константы, описывающие версию плагина. Константы используются как в rc-файле, так и в функции GetGlobalInfoW.
Мультиязычный интерфейс.
Для корректного отображения языкозависимых строк плагину достаточно выполнить несколько требований:
  • Держать строки в файлах *.lng
  • Вызывать нужные строки по номеру с помощью АПИ-функции PluginStartupInfo::GetMsg
...

Функционал.

...

PluginRinG.
Чтобы наше творение заметили и оценили, воспользуемся услугами централизованного хранилища плагинов - PlugRinG.
Для этого необходимо запаковать набор файлов по следующим правилам:
...

Re: Простой плагин (draft)

Posted: Mon 01 Apr, 2013 08:25
by Skirda
Что это?

Это черновые наброски, описывающие создание простого плагина (первый пост будет правится по мере "поступления информации" :-))

Очень надеюсь, что с вашей помощью появится вменяемая статья, которая позволит понять новичкам смысл слова "плагин" (и что это не на столько сложно, как кажется).

Так же есть идея вложить в эту статью некий шаблон по написанию и сопровождению плагинов - "правила хорошего тона" (в том числе небольшой mini howto по загрузке и поддержки плагина на плагринге).

Re: Простой плагин (draft)

Posted: Thu 13 Feb, 2014 19:56
by techie
Полезная статья. А зачем GUID нужен?

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 06:47
by Skirda
techie wrote:Полезная статья. А зачем GUID нужен?
Уникальный "неизменяемый" (в отличии от MD5 и еже с ним) идентификатор объекта.

На счет полезности статьи. Она была бы более пользительна, если бы была закончена :oops:
Помочь никто не желает?

ЗЫ.
Я так понял, в одной из соседних веток ответ уже был.

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 16:50
by techie
Skirda wrote:
techie wrote:Полезная статья. А зачем GUID нужен?
Уникальный "неизменяемый" (в отличии от MD5 и еже с ним) идентификатор объекта.
Речь конкретно о плагине. Почему нельзя просто имя использовать? Ведь есть плагринг, и если имя уже использовано, можно поменять.

Помочь сложно, потому что весь тулчейн и морока с С требуют гробить уйму времени. Интересен пример написания плагина, который позволит делать плагины на том же питоне, например, но без всяких повершелов. Т.е. динамическое подключение и отключение плагинов прямо во время работы. Фар такое умеет?

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 17:06
by HaRT
techie wrote:
Skirda wrote:
techie wrote:Полезная статья. А зачем GUID нужен?
Уникальный "неизменяемый" (в отличии от MD5 и еже с ним) идентификатор объекта.
Речь конкретно о плагине. Почему нельзя просто имя использовать? Ведь есть плагринг, и если имя уже использовано, можно поменять.
Предлагаю это обсуждать в другой ветке:
HaRT wrote:
techie wrote:почему скрипты не могут работать по имени плагина?
Потому что нет единого центра регистрации имён плагинов и никто не хочет повторения путаницы, которая много лет была, например, с Advanced Compare. А вероятность совпадения UUIDов пренебрежимо мала.
techie wrote:динамическое подключение и отключение плагинов прямо во время работы. Фар такое умеет?
Умеет.
Пользуйтесь поиском по форуму. Тут это офтопик. :evil:

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 17:58
by DrKnS
techie wrote:Речь конкретно о плагине. Почему нельзя просто имя использовать? Ведь есть плагринг, и если имя уже использовано, можно поменять.
Во-первых, потому что это красиво.
Во-вторых, поезд ушёл, ломать api уже никто не будет, привыкайте жить с уидами.
Помочь сложно, потому что весь тулчейн и морока с С требуют гробить уйму времени.
Да ну. Мингв сейчас пакуют со всем барахлом так, что доступно даже домохозяйкам в два клика, а питонистам - морока?
Интересен пример написания плагина, который позволит делать плагины на том же питоне, например
Там. Для того же питона вроде бы кто-то уже даже начал делать.

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 19:49
by techie
DrKnS wrote:
techie wrote:Помочь сложно, потому что весь тулчейн и морока с С требуют гробить уйму времени.
Да ну. Мингв сейчас пакуют со всем барахлом так, что доступно даже домохозяйкам в два клика, а питонистам - морока?
С тулчейном проблема компилять и перезапускать постоянно, но уйму времени отнимает сам С - эти все пойнтеры, скобки, значки умножения и головняк о грамотном распределении памяти, не говоря уже о базовых операциях там со строками. В общем после питона реально страдание.

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 20:04
by HaRT

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 20:30
by techie
Я свой интерес изложил. Пересечёмся - помогу с написанием туториала для питона, а нет, так нет.

Re: Простой плагин (draft)

Posted: Fri 14 Feb, 2014 21:29
by John Doe
techie wrote:С тулчейном проблема компилять и перезапускать постоянно, но уйму времени отнимает сам С - эти все пойнтеры, скобки, значки умножения и головняк о грамотном распределении памяти, не говоря уже о базовых операциях там со строками. В общем после питона реально страдание.
Уже много лет как существует LuaFAR.
Но да, наверняка найдётся другая причина почему он вам не подходит.