Я сделал так - выбираю все 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); ... |
|