Выбираем все 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);
...
--------------------------------------------------------------------------------
...
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);
...
2009-03-07 • Просмотров [ 3835 ]