AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit TInterfaceList

Ein Thema von Die Muhkuh · begonnen am 14. Feb 2005 · letzter Beitrag vom 16. Feb 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#1

Problem mit TInterfaceList

  Alt 14. Feb 2005, 14:57
Hi,

erstmal sorry für den Titel, aber ich kann das Problem nicht genauer beschreiben.

Delphi-Quellcode:
procedure Tfmain.AddPlugInButton(const Name: String; FileName: String;
  Tag: Integer);
var
  Item: TTBXCustomItem;
begin
  Item := TTBXCustomItem.Create(tbPlugIns);
  Item.Caption := Name;
  Item.OnClick := PlugInClick;
  Item.Tag := Tag;
  tbPlugIns.Add(Item);
end;

procedure Tfmain.LoadPlugIns;
type
  TInitPlugIn = function: IPlugIn; stdcall;
var
  SR: TSearchRec;
  hDll: HWND;
  aProc: TInitPlugIn;
  fProc: TFarProc;
  iPlg: IPlugIn;
  I: Integer;
begin
  I := 0;

  if FindFirst(ExePath + 'PlugIns\*.dll', faAnyFile, SR) = 0 then
  begin
     repeat
       hDll := LoadLibrary(PChar(ExePath + 'PlugIns\' + SR.Name));

       fProc := GetProcAddress(hDll, 'InitPlugIn');

       if fProc <> nil then
       begin
         aProc := fProc;

         iPlg := aProc;
         AddPlugInButton(IPlg.GetName, ExePath + 'PlugIns\' + SR.Name, I);
         PlugInList.Add(iPlg);
         Inc(I);
         iPlg := nil;
       end
       else
       begin
         Exception.CreateFmt('Kann InitPlugIn im PlugIn %s nicht finden!',
           [SR.Name]);
       end;

       FreeLibrary(hDll);
     until FindNext(SR) <> 0;
  end;

  if PlugInList.Count = - 1 then
    tbPlugIns.Enabled := false
  else
    tbPlugIns.Enabled := true;
end;

procedure Tfmain.PlugInClick(Sender: TObject);
var
  mApp: TApp;
begin
  mApp := TApp.Create;
  (PlugInList[(Sender as TTBXCustomItem).Tag] as IPlugIn).Execute(mApp); // Hier kommt eine Zugriffverletzung
  FreeAndNil(mApp);
end;
Die PlugIn-Schnittstelle ist die von ipb oder ibp (weiß nicht mehr genau wie rum ).

Die Schnittstelle ist noch nicht erweitert, ich wollte erstmal sehen wie ich die ganzen PlugIns lade.
  Mit Zitat antworten Zitat
Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#2

Re: Problem mit TInterfaceList

  Alt 14. Feb 2005, 15:22
Hi,
Soweit ich weiß greift man auf Elemente einer InterfaceListe per QueryInterface zu:

Delphi-Quellcode:
  PlugInList[(Sender as TTBXCustomItem).Tag].QueryInterface(IPlugIn, iPlg);
  if Assigned(iPlg) then begin
    ...
  end;
grüße, daniel
Daniel
Testen ist feige!
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Problem mit TInterfaceList

  Alt 14. Feb 2005, 17:11
Hi Daniel,

geht leider auch nicht. Bekomme immernoch eine AV an der gleichen Stelle.

Delphi-Quellcode:
procedure Tfmain.PlugInClick(Sender: TObject);
var
  mApp: TApp;
  iPlg: IPlugIn;
begin
  mApp := TApp.Create;

  PlugInList[(Sender as TTBXCustomItem).Tag].QueryInterface(IPlugIn, iPlg); // <<<--- AV!

  if Assigned(iPlg) then
  begin
    iPlg.Execute(mApp);
  end;

  iPlg := nil;

  FreeAndNil(mApp);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#4

Re: Problem mit TInterfaceList

  Alt 14. Feb 2005, 17:22
Hi,

habs das jetzt nochmal so versucht:

Delphi-Quellcode:
procedure Tfmain.PlugInClick(Sender: TObject);
var
  mApp: TApp;
  iPlg: IPlugIn;
begin
  mApp := TApp.Create;

  with PlugInList do // Hier kommt die AV!!!
  begin
    Items[(Sender as TTBXCustomItem).Tag].QueryInterface(IPlugIn, iPlg);
  end;

  if Assigned(iPlg) then
  begin
    iPlg.Execute(mApp);
  end;

  iPlg := nil;

  FreeAndNil(mApp);
end;
Anscheinend liegt es irgendwie an der PlugInList ?!?

[edit] Argh. Ich wollte eigentlich den Beitrag oben editieren [/edit]
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: Problem mit TInterfaceList

  Alt 14. Feb 2005, 17:32
Du vermischt hier 2 Dinge:
ENTWEDER du arbeitest mit herkömmlichen DLLs; dann kannst du nach diesen suchen, mit LoadLibrary laden und dir eine Funktion mit GetProcAddr rauspicken

ODER du arbeitest mit COM/DCOM Interfaces. Dann läuft das Erzeugen eines Interface ganz anderst ab.
Es hat nicht zu tun mit LoadLibrary.

Du ladest mit LoadLibrary eine DLL, holst die eine Funktion namens InitPlugIn, rufst die Funktion
auf und gehst davon aus, dass es ein Interfacepointer sei.
Dann rufst du FreeLibrary auf; das ist nicht wirklich sauber.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#6

Re: Problem mit TInterfaceList

  Alt 14. Feb 2005, 17:33
Hi,

hier mal die anderen Units:

udcplugin:

Delphi-Quellcode:
unit udcplugin;

interface

const
  PLUGIN_VERSION = '0.0';

type
  IEditor = interface;
  IApp = interface;
  IPlugIn = interface;

  IPlugIn = interface
    ['{8E5F6F87-BD7C-4F51-A2B1-36E437E20648}']
    { GetName liefert den Namen des PlugIns, der im Menü verwendet wird }
    function GetName: WideString; stdcall;
    { GetVersion lieft die Versionsnummer }
    function GetVersion: Integer; stdcall;
    { GetPlugInVersion liefert die Version der PlugIn-Schnittstelle }
    function GetPlugInVersion: WideString; stdcall;
    { Execute wird von der Anwendung aufgerufen, wenn der Benutzer auf
      den Menüpunkt klickt. }

    function Execute(App: IApp): Integer; stdcall;
  end;

  IApp = interface
    ['{8E5F6F87-BD7C-4F51-A2B1-36E437E20648}']
    { GetEditor liefert ein Interface auf den Editor }
    function GetEditor: IEditor; stdcall;
    { Terminate beendet das Programm }
    procedure Terminate; stdcall;
  end;

  IEditor = interface
    ['{8E5F6F87-BD7C-4F51-A2B1-36E437E20648}']
    function CaretX: Integer; stdcall;
    function CaretY: Integer; stdcall;

    procedure Clear; stdcall;
    procedure SetContent(const Value: WideString); stdcall;
    function GetContent: WideString; stdcall;

    property Content: WideString read GetContent write SetContent;
  end;

implementation

end.
Test.dll (ein kleines PlugIn):

Delphi-Quellcode:
library test;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }

  

uses
  udcplugin;

{$R *.res}

type
  TPlugIn = class(TInterfacedObject, IPlugIn)
    function GetName: WideString; stdcall;
    function GetVersion: Integer; stdcall;
    function GetPlugInVersion: WideString; stdcall;
    function Execute(App: IApp): Integer; stdcall;
  end;

function TPlugIn.GetName: WideString;
begin
  Result := 'Mein &TestPlugIn';
end;

function TPlugIn.GetVersion: Integer;
begin
  Result := (1 shl 16) or 0;
end;

function TPlugIn.Execute(App: IApp): Integer;
var
  Temp: WideString;
begin
  Result := 1;

  Temp := App.GetEditor.Content;
  App.GetEditor.Content := Temp;
end;

function InitPlugIn: IPlugIn; stdcall;
begin
  Result := TPlugIn.Create;
end;

function TPlugIn.GetPlugInVersion: WideString;
begin
  Result := PLUGIN_VERSION;
end;

exports
  InitPlugIn;

begin
end.
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Problem mit TInterfaceList

  Alt 15. Feb 2005, 15:15
*push*
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#8

Re: Problem mit TInterfaceList

  Alt 15. Feb 2005, 16:19
Hi,

das soll jetzt kein Push sein, ich hab was neues rausgefunden.

Und zwar liegt es daran, das ich iPlg nach dem hinzufügen auf nil setze. Wenn ich die Zeile auskommentiere mit dem iPlg := nil; bekomme ich bei FreeLibrary eine Zugriffverletzung.

Ich hab das nun so gelöst, dass ich die hDll public gemacht hab und immer wieder über die hDll neue PlugIns lade und erst im Form.Destroy FreeLibrary(hDll) ausführe. Ich denke das ich zwar nicht sehr sauber, aber bis ich eine andere Lösung habe, wohl das beste...
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#9

Re: Problem mit TInterfaceList

  Alt 15. Feb 2005, 17:03
Zitat von Spider:
das soll jetzt kein Push sein, ich hab was neues rausgefunden.

Und zwar liegt es daran, das ich iPlg nach dem hinzufügen auf nil setze. Wenn ich die Zeile auskommentiere mit dem iPlg := nil; bekomme ich bei FreeLibrary eine Zugriffverletzung.

Ich hab das nun so gelöst, dass ich die hDll public gemacht hab und immer wieder über die hDll neue PlugIns lade und erst im Form.Destroy FreeLibrary(hDll) ausführe. Ich denke das ich zwar nicht sehr sauber, aber bis ich eine andere Lösung habe, wohl das beste...
Die saubere Lösung:
1.) du definierst eine Komponenten Kategorie (hat nichts mit Delphi Komponenten zu tun)
mit der function CreateComponentCategory
2.) beim Registrieren der ActiveX DLL werden die CoClass in diese Katergorie registriert

3.) deine Anwendung braucht die PlugIn DLL nicht auf der Platte zu suchen, sondern fragt die
Liste deiner Komponenten Kategorie ab. (function GetCategoryCLSIDList)
4.) mit dieser Liste lassen sich die PlugIn Interfaces dynamisch erzeugen.
Angehängte Dateien
Dateityp: pas comcat_233.pas (4,4 KB, 17x aufgerufen)
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Die Muhkuh
Die Muhkuh

Registriert seit: 21. Aug 2003
7.332 Beiträge
 
Delphi 2009 Professional
 
#10

Re: Problem mit TInterfaceList

  Alt 16. Feb 2005, 12:41
Hi shima,

danke für die Unit, aber ähm irgendwie weiß ich nicht so recht, wie ich das anstellen soll.

Könntest du mir ein kleines Beispiel schreiben (Exe + ne PlugInDll)?

Wäre echt nett von dir
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz