{ This file is part of the Mufasa Macro Library (MML) Copyright (c) 2009 by Raymond van Venetiƫ and Merlijn Wajer MML is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MML is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with MML. If not, see . See the file COPYING, included in this distribution, for details about the copyright. Plugins Class for the Mufasa Macro Library } unit plugins; { Problems with SMART; you cannot free the plugin when smart is open.. Therefore, loading & free-ing plugins per script run is not an option. Assigning a TMPlugin per Tab might be a do-able solution, but will still cope with the SMART Problems.. So the question is: Plugins Per Tab,Per Run or Global? } {$mode objfpc}{$H+} interface uses Classes, SysUtils, dynlibs, libloader; const cv_StdCall = 0; //StdCall cv_Register = 1; //Register type TMPluginMethod = record FuncPtr : pointer; FuncStr : string; FuncConv: integer; end; TMPlugin = record Methods : Array of TMPluginMethod; MethodLen : integer; end; TMPluginArray = array of TMPlugin; { TMPlugins } TMPlugins = class (TGenericLoader) private Plugins : TMPluginArray; NumPlugins : integer; protected function InitPlugin(plugin: TLibHandle): boolean; override; public property MPlugins : TMPluginArray read Plugins; property Count : integer read NumPlugins; end; implementation uses MufasaTypes,FileUtil; { TMPlugins } function TMPlugins.InitPlugin(plugin: TLibHandle): boolean; var pntrArrc : function : integer; stdcall; GetFuncInfo : function (x: Integer; var ProcAddr: Pointer; var ProcDef: PChar) : Integer; stdcall; GetFuncConv : function (x: integer) : integer; stdcall; GetTypeCount : function : Integer; stdcall; GetTypeInfo : function (x: Integer; var sType, sTypeDef: string): Integer; stdcall; PD : PChar; pntr : Pointer; arrc, ii : integer; begin Pointer(pntrArrc) := GetProcAddress(plugin, PChar('GetFunctionCount')); if pntrArrc = nil then begin result:= false; exit; end; Pointer(GetFuncInfo) := GetProcAddress(plugin, PChar('GetFunctionInfo')); if GetFuncInfo = nil then begin result:= false; exit; end; Pointer(GetFuncConv) := GetProcAddress(plugin,pchar('GetFunctionCallingConv')); arrc := pntrArrc(); SetLength(Plugins,NumPlugins+1); Plugins[NumPlugins].MethodLen := Arrc; SetLength(Plugins[NumPlugins].Methods, ArrC); pd := StrAlloc(255); for ii := 0 to ArrC-1 do begin; if (GetFuncInfo(ii, pntr, pd) < 0) then Continue; Plugins[NumPlugins].Methods[ii].FuncPtr := pntr; Plugins[NumPlugins].Methods[ii].FuncStr := pd; if GetFuncConv <> nil then Plugins[NumPlugins].Methods[ii].FuncConv := GetFuncConv(ii) else Plugins[NumPlugins].Methods[ii].FuncConv := cv_stdcall; end; StrDispose(pd); inc(NumPlugins); result:= true; end; end.