Как работать с плагинами
Автор: Nomadic
Я сделал так - выбираю все 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);
...
|
|