| Autor |
Beitrag |
Ak-Alex
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 06.10.03 20:31
Hallo,
ich habe vor ein Programm zu schreiben indem ich Plugins einbinden kann, weiß aber leider noch nciht genau wie ich vorgehen muss...
Ich möchte die Plugins als Dlls einbinden, doch ich habe nie zuvor mit dlls gearbeitet. Weiß da jemand Tut's?
Sind dll's immer direkt mit nonvcl Programmierung verbunden?
Vile Fragen, ich hoffe mir kann jemand Helfen...
|
|
BungeeBug
      
Beiträge: 901
|
Verfasst: Mo 06.10.03 20:58
Hi,
dll proggen is genau so wie nen normales Progamm auch. Kannst also beides machen, jenachdem was die besser passt
Und zu den Tuts, guck mal auf www.delphi-treff.de oder bei den andern Tutorials
|
|
CodeWicht
      
Beiträge: 90
Win98, WinXP
D6
|
Verfasst: Mo 06.10.03 21:11
ein gutes tut findest du unter:
DLL-Tut
Du musst im vornherein wissen, was dein programm, bzw. deine zukünftigen plugins leisten sollen. demnach musst du entscheiden, ob du die statische einbindung, die dynamische oder die dynamisch-dynamische(Funktionen aus DLLs benutzen, die bei der Kompilierung des Programms noch gar nicht bekannt sind) benutzen willst, oder alle
In Dlls kann man eigentlich alles reinpacken, was geht, Formulare, Ressourcen, nonVCL etc.
Ich selbst habe ein Plugin-System auf Basis von DLLs geschrieben (siehe TitanBox im Freeware-Teil). Bei Problemen kann ich dir gerne weiterhelfen.
Grüsse, CodeWicht.
_________________ The equal is true.
|
|
MSCH
      
Beiträge: 1448
Erhaltene Danke: 3
W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
|
Verfasst: Mo 06.10.03 21:41
Für PlugIns kommt statische Bindung nicht in Frage, da zur Laufzeit die DLL vorhanden sein muss! Also Dynamische Bindung - ist für Plugins sowieso besser.
grez
msch
_________________ ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
|
|
Ak-Alex
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 06.10.03 21:43
Ok, aber wie kann ich auf die Formulare und Resourcen einer dll zugreifen?
Das normale Prinzip der functionen habe ich verstanden....
hmm
|
|
obbschtkuche
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 06.10.03 22:03
du kannst in einer Dll ein Formular anzeigen lassen, falls du das meinst.
Für Ressourcen, guck dir mal LoadResource an.
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Di 07.10.03 10:11
Dann möchte ich mal auf mein Tutorial hinweisen  Der zweite Teil behandelt auch PlugIns welche ein Form zur Einrichtung von ShortCuts bieten welche wiederum die Hauptanwendung manipulieren - ergo - eigentlich die gesamte Palette der Grundbedürfnisse abdecken.
PlugIns in eigenen Anwendungen

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
Ak-Alex
Gast
Erhaltene Danke: 1
|
Verfasst: Di 07.10.03 18:02
Danke für die ganzen Tipps!
THX
|
|
CenBells
      
Beiträge: 1547
Win 7
Delphi XE5 Pro
|
Verfasst: Di 07.10.03 19:38
@Sakura, machst du noch ein tutorial über plugins mit interfaces?
Und was mich ganz doll interessiert (weil ich es b isher nicht hinbekommen habe) sind frames in einem plugin unterzubringen.
Gruß
Ken
_________________ Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Di 07.10.03 22:07
Frames habe ich noch nicht in PlugIns versucht *g* Aber das liegt daran, daß ich die Frame-Technologie nicht sonderlich mag. An den Interfaces werde ich mich bestimmt mal ranmachen - nutzt unsere Software ja auch.

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
CenBells
      
Beiträge: 1547
Win 7
Delphi XE5 Pro
|
Verfasst: Di 07.10.03 22:16
das hört sich gut an.
Wenn ich dich richtig verstehe sind deine plugins doch dlls, oder?
Gruß
Ken
_________________ Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Di 07.10.03 22:31
Ich würde mich für BPL plugIns entscheiden, weil das der 'native' weg ist delphi code einzubinden...damit kann man sollte man locker frames einbinden können.
kannst ja mal diesen artikel von Borland lesen:
community.borland.co...0,1410,27178,00.html
_________________ mfg.
mâximôv
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Di 07.10.03 22:45
BPLs sind für Frames sicher die beste Lösung, allerdings muss man auch die Nachteile sehen. BPLs sollte man generell nur mit der gleichen Delphi-Compiler-Version erstellen (auch Updates des Compilers). Das bringt natürlich Nachteile, wenn man die Schnittstellen auch Programmierern anderer Firmen zur Verfügung stellen will - wären aber die logische Weiterführung zu meinem Tutorial
Wie dem auch sei, werde ich die Interfaces als nächstes in Angriff nehmen, da man damit halt auch MS C++ und VB Entwicklern die Möglichkeit gibt auf die PlugIns-Schnittstellen korrekt zu reagieren

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
CenBells
      
Beiträge: 1547
Win 7
Delphi XE5 Pro
|
Verfasst: Di 07.10.03 23:26
danke, das mit den bpls habe ich schon oft versucht, aber möchte mich eher dagegen entscheiden. Ich spiele nach einiger zeit der Pause mal wieder mit frames und dlls rum.
Jetzt habe ich etwas ganz merkwürdiges. wenn ich einen string an die dll übergebe bekomme ich immer fehlermeldungen. (Sharemem ist eingebunden)
ich habe ein interface definiert
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| IPluginFrame = interface ['{5A3D518B-76B8-4867-B7AC-3233AE9DF2FD}'] function igettext: String; procedure IcbsetParent(AParent: THandle); function igetself:TFrame; procedure isettext(Atext: String); end; |
und die implementierung im frame sieht so aus
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TFrame1.isettext(Atext: String); begin application.MessageBox(PChar(AText), 'hilfe'); end; |
den zugriff auf das frame in der dll mache ich so
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| function getPluginFrame(AApplication: TApplication): TFrame;
implementation
uses SysUtils;
var vFrame: TFrame1;
function getPluginFrame(AApplication: TApplication): TFrame; begin Application := AApplication; if not assigned(vFrame) then vFrame := TFrame1.Create(Application); result := vFrame; end;
library pluginFrame;
uses Sharemem, SysUtils, Classes, frameplugintest in 'frameplugintest.pas' , dllexport in 'units\dllexport.pas';
{$R *.res}
exports getPluginFrame;
begin end. |
in meiner mainexe sieht der code so aus
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| function getPluginFrame(AApplication: TApplication): TFrame; external 'pluginFrame.dll';
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var LIntf: IPluginFrame; begin FPluginFrame := getPluginFrame(Application); Panel1.Caption := FPluginFrame.ClassName; FPluginFrame.Parent := Panel2; if supports(FPluginFrame, IPluginFrame, LIntf) then LIntf.isettext('HALLO WELTENBUMMLER EREWRW RWER WERWERW RWE RWE R WER'); end; |
Das auslesen des classnamen klappt, das interface bekomme ich auch, aber dann hört der spaß auf.
Woran könnte das liegen?
Gruß
Ken
_________________ Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Mi 08.10.03 10:34
| sakura hat folgendes geschrieben: | BPLs sind für Frames sicher die beste Lösung, allerdings muss man auch die Nachteile sehen. BPLs sollte man generell nur mit der gleichen Delphi-Compiler-Version erstellen (auch Updates des Compilers).
... |
 Wusste ich garnicht...kann man das nicht irgendwie standardisieren oder umgehen? ...das wäre ja ein gravierender nachteil  ..doch was ist mit bisschen älteren componenten, die können ja auch in BPLs sein...die müssen dann doch noch funktionieren?
_________________ mfg.
mâximôv
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Mi 08.10.03 13:29
| maximus hat folgendes geschrieben: | | doch was ist mit bisschen älteren componenten, die können ja auch in BPLs sein...die müssen dann doch noch funktionieren? |
Auch (Gerade) für Komponenten benötigst Du immer die BPLs, welche mit der entsprechenden Compilerversion erstellt wurden

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Mi 08.10.03 15:14
 Scheise *g*
...hab mit DLLs noch nicht so viel gemacht: Ist es möglich normale klassen (oder VCL klassen) in DLLs zu packen, diese dann zu registrieren, und normal zu benutzen? ...und wie muss die VCL dann gebunden werden (sie darf ja nur einmal im projekt vorkommen und die DLL muss sie auch kennen)? ...vielleicht via BPL, wobei wir wieder ein problem hätten ???
_________________ mfg.
mâximôv
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Mi 08.10.03 15:34
Teilweise, deswegen hatte ich in meinem Tutorial auch geschrieben, daß die Technik mit Vorsicht zu genießen ist. Borland behält sich das Recht vor, die Basisklassen deren Bedürfnissen von Version zu Version anzupassen. Sonst wären Erweiterungen wie z.B. Anchors, Constraints und änhliches nie möglich gewesen.
Wenn man eigene Klassen erstellt, welche direkt von TObject abgeleitet sind, dann ist man relativ sicher, daß auch andere Delphi-Compiler Versionen mithalten können, da sich diese Klasse nicht so oft ändert.
Delphi 3 Version von TObject
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| TObject = class constructor Create; procedure Free; class function InitInstance(Instance: Pointer): TObject; procedure CleanupInstance; function ClassType: TClass; class function ClassName: ShortString; class function ClassNameIs(const Name: string): Boolean; class function ClassParent: TClass; class function ClassInfo: Pointer; class function InstanceSize: Longint; class function InheritsFrom(AClass: TClass): Boolean; procedure Dispatch(var Message); class function MethodAddress(const Name: ShortString): Pointer; class function MethodName(Address: Pointer): ShortString; function FieldAddress(const Name: ShortString): Pointer; function GetInterface(const IID: TGUID; out Obj): Boolean; class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry; class function GetInterfaceTable: PInterfaceTable; function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): Integer; virtual; procedure DefaultHandler(var Message); virtual; class function NewInstance: TObject; virtual; procedure FreeInstance; virtual; destructor Destroy; virtual; end; |
Delphi 7 Version von TObject
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| TObject = class constructor Create; procedure Free; class function InitInstance(Instance: Pointer): TObject; procedure CleanupInstance; function ClassType: TClass; class function ClassName: ShortString; class function ClassNameIs(const Name: string): Boolean; class function ClassParent: TClass; class function ClassInfo: Pointer; class function InstanceSize: Longint; class function InheritsFrom(AClass: TClass): Boolean; class function MethodAddress(const Name: ShortString): Pointer; class function MethodName(Address: Pointer): ShortString; function FieldAddress(const Name: ShortString): Pointer; function GetInterface(const IID: TGUID; out Obj): Boolean; class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry; class function GetInterfaceTable: PInterfaceTable; function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HResult; virtual; procedure AfterConstruction; virtual; procedure BeforeDestruction; virtual; procedure Dispatch(var Message); virtual; procedure DefaultHandler(var Message); virtual; class function NewInstance: TObject; virtual; procedure FreeInstance; virtual; destructor Destroy; virtual; end; |
Beide Versionen führen keine neuen Felder ein und sind soweit schon mal zueinander kompatibel, allerdings wurden in Delphi 4 oder 5  einige Änderungen eingebracht.
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| // V3 procedure Dispatch(var Message); // V7 procedure Dispatch(var Message); virtual;
// V3 function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): Integer; virtual; // V7 function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HResult; virtual;
// V3 // gabs nicht ;-) // V7 procedure AfterConstruction; virtual; procedure BeforeDestruction; virtual; |
Dadurch kann es zu Konflikten kommen, die man vorher eingehendst studieren sollte und ggf. den Gebrauch jeglicher Basismethoden durch den Programmierer ausschließen. An dieser Stelle verweise ich mal auf folgendes Tutorial Ändern der Klassenhierarchie, die dort gezeigten Techniken dürfen zum Beispiel auch nicht genutzt werden, wenn man Klassennutzung über DLLs zulässt, da die verschiedenen Delphi-Version unterschiedlich VMT's nutzen.
Das ist auch der Grund, warum ich mal endlich den nächsten Teil des PlugIn Tuts machen sollte, damit man sich den Interfaces (ab IDispatch) annehmen kann, die viele der hier aufgeführten Probleme lösen

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: Mi 08.10.03 21:41
 Danke für diese weisen worte *g* ...du scheinst es wirklich präzise zu wissen...schöne antwort das.
Das klassen-injezierungs-gelöt gefällt mir auch sehr gut! ...was ist eigentlich, wenn ich features einer, injezierten klasse, schon im code nutzen will? ...*überlegt*...würde aber auch keinen sinn machen und der compiler weiss ja noch nix von seinem glück *g*
Kann ich mit der technik auch eine klasse vor TObject schalten?
Mit den plugIns überleg ich noch, welche technik ich einsetzen werde...
mfg
_________________ mfg.
mâximôv
|
|
sakura
      
Beiträge: 137
W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
|
Verfasst: Do 09.10.03 10:54
| maximus hat folgendes geschrieben: | | Kann ich mit der technik auch eine klasse vor TObject schalten? |
Es ist prinzipiell möglich, wird jedoch nicht viel bringen da - TObject Methoden die Vorgänger nicht aufrufen - damit keine der Methoden autmatisch angegangen wird
- Ich ir nicht 100% sicher bin, ob Delphi im Hintergrund noch ein Ass im Ärmel hält
- Du die neuen Methoden zur Designzeit nicht direkt nutzen kannst, da die Klasse die nicht kennt.
- Es kann sein, daß die VMT zerstört wird - ausprobieren (aber auf eigene Gefahr)
Die Methoden, wie im Tutorial vorgestellt unterbinden die Möglichkeit durch folgende Zeile:
Delphi-Quelltext 1: 2:
| if clSuccessor.ClassParent = nil then raise Exception.Create('Successor Class has no parent to be replaced.'); |
Da wird abgefangen, da die zu ändernde Klasse einen Vorgänger hat. Änderst Du diesen bei TObject musst Du darauf achten, daß der neue Vorgänger keinen Vorgänger hat - er muss auf nil gesetzt werden, sonst gibt es garantiert einige Probleme

_________________ Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
|
|
Ist die Frage beantwortet? Das Problem gelöst?
Dann klicke hier, um das Thema entsprechend zu markieren!
|
|