![]() |
Benutzen von Klassen aus einer DLL
Liste der Anhänge anzeigen (Anzahl: 1)
Moin !
Haut mich nicht gleich aber ich habe da was im Netz gefunden und wollte euch mal um eure Meinung bitten. ![]() Dort schreibt Andreas Kosch: Zitat:
Aber ich stell mir schon die Frage was von diesem Konstrukt zu halten ist. Wie ist da eure Meinung? |
AW: Benutzen von Klassen aus einer DLL
Moin nochmal,
ich habe die Klasse nochmal erweitert um ein Formular und ein NrComm (serielle Komponente).
Delphi-Quellcode:
Dann habe ich in der anwendung zwei Instanzen erstellt:
unit Obj_Unit;
interface Uses nrclasses, nrcomm, Forms, Unit2; type TMWSt = class protected nrcomm : TnrComm; Form : TTestForm; public function GetBrutto (const aNetto : Currency): Currency; virtual; abstract; procedure SetPercent(const aPercent : Integer ); virtual; abstract; Function ShowPortInfo : string; virtual; abstract; published property Comm : TnrComm read nrcomm write nrcomm; property Formular : TTestForm read Form write Form; end; const MWST_VERSION = 1; implementation end.
Delphi-Quellcode:
Und natürlich in der DLL die Funktion ergänzt.
Obj1 := CreateMWStObj;
Obj1.Comm := nrComm1; Obj1.Formular := TTestForm.Create(Self); Obj1.Formular.Show; Obj2 := CreateMWStObj; Obj2.Comm := nrComm2; Auch das funktioniert. Habe mir auf das Formular 2 Buttons gesetzt um jeweils ShowPortInfo der Instanz aufzurufen. Klappt bis jetzt tadellos. Aber ich bin mir irgendwie fast sicher das diese Technik einen Haken hat :gruebel: |
AW: Benutzen von Klassen aus einer DLL
Die Dll hält ja nur die Referenzen. Die eigentliche Funktionalität implementierst du ja im Hauptprogramm
|
AW: Benutzen von Klassen aus einer DLL
"virtual" definiert ja nur Referenzen (eine Index-Nummer) auf die Funktionen der Klasse, über die VMT.
Jedes Modul (EXE/DLL) hat seine eigene RTTI. Nun läßt Delphi gerne Ungenutztes weg. (Optimierung) Wenn man nun also eine Funktion in der DLL/EXE nutzt, aber im Anderen nicht, dann enthalten beide RTTIs unterschiedliche VMTs, welches sehr schöne Effekte ergibt, da so falsche Funktionen aufgerufen werden, wenn man über Modulgrenzen hinweg mit Objekten arbeitet. Ich kann davon ein Lied singen. Das war der Grund, warum es die DLL-Version meines himXML nicht mehr gibt, also die alte Version mit den Objekten. (die neue Interface-Version wird hoffentlich bald erscheinen) Fazit, es ist nicht ratsam Objekte über Modulgrenzen hinweg zu nutzen, außer bei Verwendung von Laufzeit-Packages. PS: Hast du auch an den Shared-MemoryManager gedacht? |
AW: Benutzen von Klassen aus einer DLL
Moin !
Zitat:
Delphi-Quellcode:
Probleme treten dann auf wenn ich diese abstrakte Klasse in der DLL nutze, aber z.B. nur Met1 implementiere und Met2 komplett weg lasse.
function Met1; virtual; abstract;
procedure Met2; virtual; abstract; Wenn ich jetzt aus meiner Anwendung eine Instanz der "DLL-Klasse" erzeuge und ich irgendwann Met2 in meinem Programm aufrufe, dann habe ich ein Problem. Wäre es dann nicht schon ausreichend wenn man in einer DLL Klasse immer alle Methoden implementiert? Auch wenn sie keinen Code enthalten? Oder trifft das noch nicht des Pudels Kern? Zitat:
|
AW: Benutzen von Klassen aus einer DLL
Nein, selbst wenn du es implementierst (in der DLL), es dann in der DLL aber nicht benutzt, dann wird dieses vom Compiler wegoptimiert.
Nun hast du ja nocheine Implementation dieser Klasse in der EXE, wo du nun diese Funktion nutzen willst und dieses hat seine eigene RTTI und weiß von der Wegoptimierung nix.
Delphi-Quellcode:
z.B.
function Met1; virtual/overload;
procedure Met2; virtual/overload; procedure Met3; virtual/overload; in DLL alles irgendwie implementiert (eventuell auch erst in Nachfahren), aber nur einen Teil irgendwo verwendet/verlinkt. In der Exe willst du aber dieses, alles oder nur'n anderen Teil nutzen. also, in der DLL: VMT-Index 0 = Met1 VMT-Index 1 = Met3 in der EXE: VMT-Index 0 = Met1 VMT-Index 1 = Met2 VMT-Index 2 = Met3 Ruft man hier in der Met2 auf, dann wird in der DLL dafür aber Met3 ausgeführt. Und bei Met3 knallt es sowieso, da es da nix gibt. Wenn in der DLL garnichts irgendwie eingebunden ist, dann seht auch nichts in dieser VMT. |
AW: Benutzen von Klassen aus einer DLL
Hmm so ganz bin ich noch nicht bei dir.
Zitat:
Da ich hier eine Klasse implementiere kann er doch erstmal gar nicht wissen was ich später in der EXE davon verwenden werde :gruebel: Könntest du evtl. das Beispiel prog (Posting 1) mal so umbauen, das es zu der von dir beschriebenen Fehlfunktion kommt? |
AW: Benutzen von Klassen aus einer DLL
Alles, was nicht in diesem Modul (EXE/DLL) verwendet wird, wird nicht mit einkompiliert.
|
AW: Benutzen von Klassen aus einer DLL
Moin !
Delphi-Quellcode:
library Device;
uses SysUtils, Dialogs, ShareMem, Classes, Obj_Unit in 'Obj_Unit.pas', nrclasses, nrcomm; type TMWSt98 = class(TMWSt) private FMWStSatz : Real; public constructor Create; function GetBrutto (const aNetto : Currency): Currency; override; procedure SetPercent(const aPercent : Integer); override; Function ShowPortInfo : string; override; end; constructor TMWSt98.Create; begin inherited Create; FMWStSatz := 1.15; Assert(MWST_VERSION = 1, 'Falsche Unit-Version!'); // nrcomm := TNrComm.Create(nil); end; function TMWSt98.GetBrutto(const aNetto: Currency): Currency; begin Result := aNetto * FMWStSatz; ShowMessage(comm.ComName); end; procedure TMWSt98.SetPercent(const aPercent : Integer); begin FMWStSatz := 1.0 + (aPercent/100); end; Function TMWSt98.ShowPortInfo : string; var Output : string; begin Comm.EnumPorts := epFullInfo; Comm.Update; output := comm.ComName + #13#10 + Comm.Device[comm.DeviceIndex].RegKey; Formular.Memo1.Lines.Add(output); ShowPortInfo := Output; end; { Schnittstellenprozedur } function CreateMWStObj: TMWSt98; stdcall; begin Result := TMWSt98.Create; end; { Export der Schnittstellenprozedur } exports CreateMWStObj; // resident; begin { nichts zu tun } end. Zitat:
|
AW: Benutzen von Klassen aus einer DLL
Moin !
Je länger ich mit dem DLL Thema rumprobiere, desto mehr komme ich zu dem Entschluss, keine DLLs zu verwenden :stupid: Egal wie man es angeht, man stößt doch immer wieder auf Probleme die man eigentlich nicht haben mag. Im Grunde wollte ich mit den DLLs Programmteile auslagern weil sie für bestimmte User unnötig sind. Aber mir ist eben eine Idee gekommen wie man es auch anders lösen könnte. Man könnte ja bestimmte Klassen bzw. Bereiche in der Anwendung in eine Compiler Direktive verpacken. In etwa so:
Delphi-Quellcode:
Dann könnte man Anwendungen mit unterschiedlichem Funktionsumfang erstellen lassen.
{$Define TESTMODE}
text := 'We are in test mode'; // Display the value of text if we are in test mode {$IfDef TESTMODE} ShowMessage('text = '+text); {$EndIf} Da das aber hier total OT wird werde ich dazu mal ein anderes Thema eröffnen. Danke jedenfalls an alle hier im Thread für die Erklärungen ! :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:05 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