![]() |
Problem mit TInterfaceList
Hi,
erstmal sorry für den Titel, aber ich kann das Problem nicht genauer beschreiben.
Delphi-Quellcode:
Die PlugIn-Schnittstelle ist die von ipb oder ibp (weiß nicht mehr genau wie rum :roteyes: ).
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 Schnittstelle ist noch nicht erweitert, ich wollte erstmal sehen wie ich die ganzen PlugIns lade. |
Re: Problem mit TInterfaceList
Hi,
Soweit ich weiß greift man auf Elemente einer InterfaceListe per QueryInterface zu:
Delphi-Quellcode:
grüße, daniel
PlugInList[(Sender as TTBXCustomItem).Tag].QueryInterface(IPlugIn, iPlg);
if Assigned(iPlg) then begin ... end; |
Re: Problem mit TInterfaceList
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; |
Re: Problem mit TInterfaceList
Hi,
habs das jetzt nochmal so versucht:
Delphi-Quellcode:
Anscheinend liegt es irgendwie an der PlugInList ?!?
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; [edit] Argh. Ich wollte eigentlich den Beitrag oben editieren :wall: [/edit] |
Re: Problem mit TInterfaceList
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. |
Re: Problem mit TInterfaceList
Hi,
hier mal die anderen Units: udcplugin:
Delphi-Quellcode:
Test.dll (ein kleines PlugIn):
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.
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. |
Re: Problem mit TInterfaceList
*push* :angel2:
|
Re: Problem mit TInterfaceList
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... |
Re: Problem mit TInterfaceList
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
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. |
Re: Problem mit TInterfaceList
Hi shima,
danke für die Unit, aber ähm :oops: 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 :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz