Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (* UNIT FOR INTERFACE *)
- {$mode objfpc}
- unit uIntf;
- interface
- type
- IOperHost = interface ['{7CE86326-AAF9-44A6-9581-69145A5ABD19}']
- procedure SetResult(d : Double);
- function GetResult : Double;
- property Result : Double read GetResult write SetResult;
- end;
- IOper = interface ['{9F409856-C54F-48F7-9205-1DEFE5FE48BE}']
- function GetMyName : WideString;
- property PluginName : WideString read GetMyName;
- procedure Execute;
- end;
- implementation
- end.
- (* PLUGIN: OPERATOR ADDITION (+) *)
- {$mode objfpc}
- library plugin_addition;
- uses
- UIntf;
- const
- MYNAME = 'addition';
- type
- TOperSoma = class(TInterfacedObject, IOper)
- private
- function GetMyName : WideString;
- public
- property PluginName : WideString read GetMyName;
- procedure Execute;
- end;
- var
- thehost : IOperHost = nil;
- procedure GetDouble(const PROMPT : string; out d : Double);
- var
- s : string;
- e : word;
- begin
- repeat
- write(PROMPT);
- readln(s);
- Val(s, d, e);
- until e = 0;
- end;
- function TOperSoma.GetMyName : WideString;
- begin
- GetMyName := MYNAME;
- end;
- procedure TOperSoma.Execute;
- var
- a, b : Double;
- begin
- writeln('You''re inside plugin ''', MYNAME, '''');
- GetDouble('a? ', a);
- GetDouble('b? ', b);
- thehost.Result := a + b;
- end;
- function OperInitialize(host : IOperHost) : IOper; stdcall;
- begin
- thehost := host;
- OperInitialize := TOperSoma.Create as IOper;
- end;
- exports
- OperInitialize;
- begin
- end.
- (* PROGRAM (HOST) *)
- {$mode objfpc}
- program intf_prgm;
- uses
- sysutils, dynlibs, uIntf;
- type
- TOperHost = class(TInterfacedObject, IOperHost)
- private
- vRes : Double;
- procedure SetResult(d : Double);
- function GetResult : Double;
- public
- property Result : Double read GetResult write SetResult;
- end;
- TOperInfo = class
- dll : TLibHandle;
- intf : IOper;
- end;
- TOperPlugins = array of TOperInfo;
- TOperInit = function (host : IOperHost) : IOper; stdcall;
- var
- myself : IOperHost = nil;
- plugins : TOperPlugins;
- procedure TOperHost.SetResult(d : Double);
- begin
- self.vRes := d;
- end;
- function TOperHost.GetResult : Double;
- begin
- GetResult := self.vRes;
- end;
- procedure PluginInitialization;
- var
- finder : TSearchRec;
- dll : TLibHandle;
- proc : TOperInit;
- plug : TOperInfo;
- begin
- if FindFirst(ExtractFilePath(ParamStr(0)) + '\plugin_*.dll', faAnyFile, finder) <> 0 then
- Exit;
- myself := TOperHost.Create as IOperHost;
- SetLength(plugins, 0);
- repeat
- dll := LoadLibrary(PChar(finder.Name));
- if dll <> NilHandle then begin
- proc := TOperInit(GetProcedureAddress(dll, 'OperInitialize'));
- if Assigned(proc) then begin
- plug := TOperInfo.Create;
- try
- plug.dll := dll;
- plug.intf := proc(myself);
- SetLength(plugins, Succ(Length(plugins)));
- plugins[High(plugins)] := plug;
- except
- plug.Free;
- end;
- end;
- end;
- until FindNext(finder) <> 0;
- FindClose(finder);
- end;
- procedure PluginFinalization;
- var
- i : word;
- begin
- if Length(plugins) = 0 then
- Exit;
- for i := Low(plugins) to High(plugins) do begin
- plugins[i].intf := nil;
- if plugins[i].dll <> NilHandle then
- if UnloadLibrary(plugins[i].dll) then
- plugins[i].dll := NilHandle;
- plugins[i].Free;
- end;
- SetLength(plugins, 0);
- end;
- begin
- try
- PluginInitialization;
- plugins[0].intf.Execute;
- writeln('Result = ', myself.Result:0:5);
- finally
- PluginFinalization;
- end;
- readln;
- end.
Advertisement
Add Comment
Please, Sign In to add comment