Советы по Delphi

         

Как работать с плагинами?


Из советов Nomadic'a:

Я сделал так - выбираю все DLL из каталога с программой, загружаю каждую и пытаюсь найти в ней функцию (через API GetProcAddress) с заранее определенным жестко именем (например что нибудь типа IsPluginForMyStuff). Если нашлась - DLL считается моим плагином, если нет - выгрузить и забыть.

А набор вызываемых функций по идее одинаков у всех плагинов, и программа (основная) в курсе какие именно функции она ищет в DLL. Если даже и не так, то ничего не мешает тебе определить в плагине функцию наподобие GetFeatures, возвращающую список строк-названий поддержанных плагином процедур.

Вот часть моего кода по работе с плагинами...

    ...
type

// Процедурные типы для хранения ссылок на функции плагинов TGetNProc=function:shortstring; TGetSProc=function:integer; TProcessProc=procedure(config:pointer; request:PRequest; var reply:PReply); TConfigProc=procedure(defcfg:PSysConfig; var config:pointer);

TSaveLoadProc=procedure(inifile:pointer; var config:pointer);
// Информация об отдельном плагине TPlugin=record Name:shortstring;                   // Полное название Filename:shortstring;               // Имя файла Handle:integer;                     // Хэндл загруженной DLL CFGSize:integer;                    // Размер конфигурации в RAM ProcessProc: TProcessProc;      // Адрес процедуры обработки ConfigProc: TConfigProc;       // Адрес процедуры настройки LoadCFG,SaveCFG:TSaveLoadProc;      // Адреса процедур чтения/записи cfg end; PPlugin=^TPlugin;
// Список загруженных плагинов TPlugins=class(TList);
...

var

Plugins:TPlugins;  sr:TSearchRec;  lib:integer; pgetn:TGetNProc;  pgets: TGetSProc;  plugin:PPlugin;
...

// Читаем плагины и создаем их список.
Plugins:=TPlugins.Create;
if FindFirst('*.dll',faAnyFile,sr)<>0 then begin
ShowMessage('Hе найдено подключаемых модулей.'); Close; end;
repeat
lib:=LoadLibrary(PChar(sr.Name)); if lib<>0 then begin @pgetn:=GetProcAddress(lib, 'GetPluginName'); if @pgetn=nil then FreeLibrary(lib)    // Hе плагин else begin New(plugin); @pgets:=GetProcAddress(lib, 'GetCFGSize'); plugin.Name:=pgetn; plugin.Filename:=sr.Name; plugin.CFGSize:=pgets; plugin.Handle:=lib; plugin.ConfigProc:=GetProcAddress(lib, 'Configure'); plugin.ProcessProc:=GetProcAddress(lib, 'Process'); plugin.SaveCFG:=GetProcAddress(lib, 'SaveCFG'); plugin.LoadCFG:=GetProcAddress(lib, 'LoadCFG'); Plugins.Add(plugin); end; end; until FindNext(sr)<>0;
FindClose(sr);
...

[001677]



Содержание раздела