thoga31

Test with interfaces (plugins) (w/ FPC)

Jan 26th, 2015
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.88 KB | None | 0 0
  1. (* UNIT FOR INTERFACE *)
  2. {$mode objfpc}
  3. unit uIntf;
  4.  
  5. interface
  6.  
  7. type
  8.    IOperHost = interface ['{7CE86326-AAF9-44A6-9581-69145A5ABD19}']
  9.       procedure SetResult(d : Double);
  10.       function GetResult : Double;
  11.       property Result : Double read GetResult write SetResult;
  12.    end;
  13.  
  14.    IOper = interface ['{9F409856-C54F-48F7-9205-1DEFE5FE48BE}']
  15.       function GetMyName : WideString;
  16.       property PluginName : WideString read GetMyName;
  17.       procedure Execute;
  18.    end;
  19.  
  20.  
  21. implementation
  22.  
  23. end.
  24.  
  25.  
  26.  
  27. (* PLUGIN: OPERATOR ADDITION (+) *)
  28. {$mode objfpc}
  29. library plugin_addition;
  30.  
  31. uses
  32.    UIntf;
  33.  
  34. const
  35.    MYNAME = 'addition';
  36.  
  37. type
  38.    TOperSoma = class(TInterfacedObject, IOper)
  39.       private
  40.          function GetMyName : WideString;
  41.       public
  42.          property PluginName : WideString read GetMyName;
  43.          procedure Execute;
  44.    end;
  45.  
  46. var
  47.    thehost : IOperHost = nil;
  48.  
  49.  
  50. procedure GetDouble(const PROMPT : string; out d : Double);
  51. var
  52.    s : string;
  53.    e : word;
  54. begin
  55.    repeat
  56.       write(PROMPT);
  57.       readln(s);
  58.       Val(s, d, e);
  59.    until e = 0;
  60. end;
  61.  
  62.  
  63. function TOperSoma.GetMyName : WideString;
  64. begin
  65.    GetMyName := MYNAME;
  66. end;
  67.  
  68.  
  69. procedure TOperSoma.Execute;
  70. var
  71.    a, b : Double;
  72. begin
  73.    writeln('You''re inside plugin ''', MYNAME, '''');
  74.    GetDouble('a? ', a);
  75.    GetDouble('b? ', b);
  76.    thehost.Result := a + b;
  77. end;
  78.  
  79.  
  80. function OperInitialize(host : IOperHost) : IOper; stdcall;
  81. begin
  82.    thehost := host;
  83.    OperInitialize := TOperSoma.Create as IOper;
  84. end;
  85.  
  86.  
  87. exports
  88.    OperInitialize;
  89.  
  90. begin
  91. end.
  92.  
  93.  
  94. (* PROGRAM (HOST) *)
  95. {$mode objfpc}
  96. program intf_prgm;
  97. uses
  98.    sysutils, dynlibs, uIntf;
  99.  
  100.  
  101. type
  102.    TOperHost = class(TInterfacedObject, IOperHost)
  103.       private
  104.          vRes : Double;
  105.          procedure SetResult(d : Double);
  106.          function GetResult : Double;
  107.       public
  108.          property Result : Double read GetResult write SetResult;
  109.    end;
  110.    
  111.    TOperInfo = class
  112.       dll  : TLibHandle;
  113.       intf : IOper;
  114.    end;
  115.    
  116.    TOperPlugins = array of TOperInfo;
  117.    TOperInit = function (host : IOperHost) : IOper; stdcall;
  118.  
  119. var
  120.    myself  : IOperHost = nil;
  121.    plugins : TOperPlugins;
  122.  
  123.  
  124. procedure TOperHost.SetResult(d : Double);
  125. begin
  126.    self.vRes := d;
  127. end;
  128.  
  129.  
  130. function TOperHost.GetResult : Double;
  131. begin
  132.    GetResult := self.vRes;
  133. end;
  134.  
  135.  
  136. procedure PluginInitialization;
  137. var
  138.    finder : TSearchRec;
  139.    dll    : TLibHandle;
  140.    proc   : TOperInit;
  141.    plug   : TOperInfo;
  142.  
  143. begin
  144.    if FindFirst(ExtractFilePath(ParamStr(0)) + '\plugin_*.dll', faAnyFile, finder) <> 0 then
  145.       Exit;
  146.    
  147.    myself := TOperHost.Create as IOperHost;
  148.    
  149.    SetLength(plugins, 0);
  150.    repeat
  151.       dll := LoadLibrary(PChar(finder.Name));
  152.      
  153.       if dll <> NilHandle then begin
  154.          proc := TOperInit(GetProcedureAddress(dll, 'OperInitialize'));
  155.          
  156.          if Assigned(proc) then begin
  157.             plug := TOperInfo.Create;
  158.            
  159.             try
  160.                plug.dll  := dll;
  161.                plug.intf := proc(myself);
  162.                SetLength(plugins, Succ(Length(plugins)));
  163.                plugins[High(plugins)] := plug;
  164.             except
  165.                plug.Free;
  166.             end;
  167.          end;
  168.       end;
  169.    until FindNext(finder) <> 0;
  170.    
  171.    FindClose(finder);
  172. end;
  173.  
  174.  
  175. procedure PluginFinalization;
  176. var
  177.    i : word;
  178. begin
  179.    if Length(plugins) = 0 then
  180.       Exit;
  181.    
  182.    for i := Low(plugins) to High(plugins) do begin
  183.       plugins[i].intf := nil;
  184.       if plugins[i].dll <> NilHandle then
  185.          if UnloadLibrary(plugins[i].dll) then
  186.             plugins[i].dll := NilHandle;
  187.       plugins[i].Free;
  188.    end;
  189.    
  190.    SetLength(plugins, 0);
  191. end;
  192.  
  193.  
  194. begin
  195.    try
  196.       PluginInitialization;
  197.       plugins[0].intf.Execute;
  198.       writeln('Result = ', myself.Result:0:5);
  199.    finally
  200.       PluginFinalization;
  201.    end;
  202.    readln;
  203. end.
Advertisement
Add Comment
Please, Sign In to add comment