Autor Beitrag
Ak-Alex
Gast
Erhaltene Danke: 1



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 901



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 90

Win98, WinXP
D6
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1448
Erhaltene Danke: 3

W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
BeitragVerfasst: 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



BeitragVerfasst: 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



BeitragVerfasst: 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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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

:welcome:

_________________
Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
Ak-Alex
Gast
Erhaltene Danke: 1



BeitragVerfasst: Di 07.10.03 18:02 
Danke für die ganzen Tipps!


THX
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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.

8)

_________________
Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: 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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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 :-)

8)

_________________
Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: 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
ausblenden 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

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TFrame1.isettext(Atext: String);
begin
  application.MessageBox(PChar(AText), 'hilfe');
  //edit1.Text := AText;
end;


den zugriff auf das frame in der dll mache ich so

ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
//subunit code
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;

//dll code

library pluginFrame;

{ 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
  Sharemem,
  SysUtils,
  Classes,
  frameplugintest in 'frameplugintest.pas' {Frame1: TFrame},
  dllexport in 'units\dllexport.pas';

{$R *.res}

exports
  getPluginFrame;

begin
end.


in meiner mainexe sieht der code so aus

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: 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 :idea: ..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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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 :?

:wink2:

_________________
Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: 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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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
ausblenden 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
ausblenden 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.

ausblenden 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 :-)

:wink2:

_________________
Das Lächeln ist die eleganteste Art dem Gegner die Zähne zu zeigen.
Borland SE
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mi 08.10.03 21:41 
:D 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
ontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 137

W2KS, W2K3S
D1Pr, D3Pr, D4Pr, D5E, D7A, D8A, D2005A
BeitragVerfasst: 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:
ausblenden 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 ;-)

:wink2:

_________________
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!