Thema: Delphi Interfaces in Liste

Einzelnen Beitrag anzeigen

Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#1

Interfaces in Liste

  Alt 7. Aug 2007, 14:10
Moin,
ich bastel grade mit interfaces rum, funktioniert soweit auch schon ganz gut...
jetzt brauche ich die möglichkeit eine variable Liste dieser Plugin-Interfaces anzulegen mit entsprechenden Zusatzdaten.
Ich hab schon ne Weile rumgesucht, aber so richtig weiter bin ich nicht gekommen. es gab einen Thread wo auf TInterfacelist verwiesen wurde, nur leider gibts das nicht bei mir (D3). auch glaube ich nicht, das mithilfe dieser zusatzdaten (wie das dll-handle etc.) mit gespeichert werden können.
Somit bleibt mir wohl nur die Selbstimplementierung...

mein Versuch:

Delphi-Quellcode:
  TPluginRec=record
    dllName,pName:string;
    hDll:integer;
    iPlg:IPlugin;
  end;
  PPluginRec=^TPluginRec;
  TPluginList=class
    FList:TList;
    public
      constructor Create;
      destructor Destroy;override;
      procedure AddPlugin(dllName:string;hDll:integer;const Plugin:IPlugin);

      function GetPlugin(index:integer):TPluginRec;
      function count:integer;
      procedure Delete(index:integer);
  end;

constructor TPluginList.Create;
begin
  inherited;
  FList:=TList.create;
end;

destructor TPluginList.Destroy;
var i:integer;
begin
  for i:=FList.count-1 downto 0 do
    delete(i);
  FList.free;
  inherited;
end;

procedure TPluginList.AddPlugin(dllName:string;hDll:integer;const Plugin:IPlugin);
var pr:PPluginRec;
begin
  new(pr);
  pr^.iPlg:=Plugin;
  pr^.hDll:=hdll;
  pr^.dllName:=dllname;
  FList.Add(pr);
end;

function TPluginList.count:integer;
begin
  result:=FList.count;
end;

function TPluginList.GetPlugin(index:integer):TPluginRec;
begin
  result:=PPluginRec(Flist.Items[index])^;
end;

procedure TPluginList.Delete(index:integer);
var pr:PPluginrec;
begin
  pr:=PPluginRec(FList.Items[index]);
  pr.iPlg:=nil; //plugininterface freigeben
  freelibrary(pr.hDll); //dll freigeben
  dispose(PPluginRec(FList.Items[index])); //speicher des records freigeben
end;

procedure TForm1.FormCreate(Sender: TObject);
type
  TProcInitPlg = function (Handle:Integer): IPlugin; stdcall;
var
  fProc: TProcInitPlg;
begin
  pList:=TPluginList.create;
  // Application-Interface laden
  app := TApp.Create(
    TMemoWrapper.Create(Memo1),
    TMenuWrapper.Create(MainMenu1),
    TToolbarWrapper.Create(Toolbar1)
  );
  // Bibliothek laden und Interface holen
  hDll := LoadLibrary(PCHAR(extractfilepath(paramstr(0)) + 'project2.dll'));
  @fProc := GetProcAddress(hDLL, 'InitPlugin');
  if @fProc <> nil then
  begin
    //iPlg := fProc(hDll);
    pList.AddPlugin('project2',hdll,fProc(hDll));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
    pr:TPluginrec;
begin
  for i:=0 to pList.count-1 do
  begin
    pr:=pList.GetPlugin(i);
    pr.iplg.Execute(app);
  end;
  // Interface verwenden
// if Assigned(iPlg) then
// iplg.Execute(app);
end;
das ganze funktioniert zwar, aber ich weis nicht, ob alles korrekt freigegeben wird, da in der Delete-Methode (vom destructor aufgerufen) nur die erste Zeile ausgeführt wird, danach ist das Programm zuende. rufe ich die Delete-Methode manuell auf, werden alle zeilen ausgeführt.
hab das auch mit d7 laufen lassen, da bekomme ich bei der zweiten Zeile eine Zugriffsverletzung. beim manuellen delete geht er alle zeilen durch und danach poppt das CPU-Fenster auf (worin ich aber nicht wirklich was erkennen kann...).

Gruß Frank
  Mit Zitat antworten Zitat