Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

FAQ - Как написать свой PLUGIN (типа поддержки различных форматов файлов ...)

© Зайцев Олег
http://z-ol.chat.ru/

Типовая задача - разрабатывается некая задача и при этом

  • Некоторые ее компоненты могут не инсталлироваться баз ущерба для работоспособности
  • Некоторые компоненты предполагается изготавливать впоследствии и рассылать пользователям
  • Некоторые компоненты могут разрабатываться другими программистами и распространяться независимо от программы
  • .....

Классические примеры - фильтры для совместимости по форматам файлов с другими программами, некоторые расширения и дополнительные возможности. Примеры и моей практики - приведу парочку

  • Программа управления программатором ПЗУ. Заранее неизвестно, с каким железом она будет работать и как им управлять. Необходимо было дать возможнось разработчику железа написать для него поддержку
  • Программа печати отчетов. Она должна печатать в любой кодировке на любой принтере, в т.ч. и экзотическом типа АЦПУ. Заранее неизвестно, какие принтеры будуп применяться совместно с ней и как ими управлять (известно только одно - драйверов под них нет и не будет) - переделывать программу под каждый принтер - неинтересно ...

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

Пример (приложение имеет одно окно, на нем кнопка):

UNIT UNIT1;

INTERFACE

USES
  WINDOWS, MESSAGES, SYSUTILS, CLASSES, GRAPHICS, CONTROLS, FORMS, DIALOGS,
  STDCTRLS;

TYPE
  TFORM1 = CLASS(TFORM)
    BUTTON1: TBUTTON;
    PROCEDURE BUTTON1CLICK(SENDER: TOBJECT);
    PROCEDURE FORMCREATE(SENDER: TOBJECT);
  PRIVATE
  PUBLIC
  END;
 // Тип "процедура". Естественно, можно определит типы
 // "функция" или "функция с параметрами" ...
 TDLLPROC = PROCEDURE;

VAR
  FORM1: TFORM1;
  DLLPROCPTR  : TDLLPROC;
  LIBINSTANCE : HMODULE; // Логический номер модуля DLL

IMPLEMENTATION

{$R *.DFM}

PROCEDURE TFORM1.BUTTON1CLICK(SENDER: TOBJECT);
BEGIN
 // Проверим, загружена ли DLL
 IF LIBINSTANCE=0 THEN BEGIN
  // Не загружена, попробуем загрузить
  LIBINSTANCE := LOADLIBRARY('PLUG_IN.DLL');
  // Проверим, успешна ли загрузка (LIBINSTANCE=0 - неуспешно)
  IF LIBINSTANCE=0 THEN BEGIN
   SHOWMESSAGE('Ошибка загрузки библиотеки PLUG_IN.DLL');
   EXIT;
  END;
  // Ищем функцию по ее имени (имя должно точно совпадать)
  DLLPROCPTR := TDLLPROC(GETPROCADDRESS(LIBINSTANCE,'MYPROC'));
  // Проверим, нашли ли (если нашли, то ASSIGNED вернет TRUE)
  IF NOT ASSIGNED(DLLPROCPTR) THEN BEGIN
   // Не нашли - выгружаем DLL из памяти
   FREELIBRARY(LIBINSTANCE);
   LIBINSTANCE:=0;
   SHOWMESSAGE('Ошибка: функция MYPROC не найдена');
   EXIT;
  END;
  // Непосредственно вызов функции
  DLLPROCPTR;
  // Выгрузка библиотеки
  FREELIBRARY(LIBINSTANCE);
  LIBINSTANCE:=0;
 END;
END;

PROCEDURE TFORM1.FORMCREATE(SENDER: TOBJECT);
BEGIN
 DLLPROCPTR:=NIL;
 LIBINSTANCE:=0;
END;

END.

Естественно, в реальной задаче имеет смысл создать свой класс, который при инициализации будет загружать библиотеку, а при уничтожении - выгружать. Кроме того, он должен иметь функцию типа "Перезагрузить библиотеку", которая будет выгружать текущую и загружать новую. DLL - обычная, естественно может иметь неограниченное количество процедур и функций.

Особенности:

  • Пока библиотека загружена, ее файл нельзя ни удалить, ни переименовать. Поэтому при возникновении ошибок следует выгружать библиотеку, иначе пользователь не сможет ее заменит (без перезагрузки ПК).
  • Обычно имеет смысл создать ряд функции типа GETINFO, GETAUTOR, GETCOPYRIGHT ..., чтобы вызывающая программа могла получить информацию о назначении данной DLL
  • Расширение DLL не является обязательным, поэтому можно применять свои расширения (например DRV)
Остальные Вопросы

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог