AGB  ·  Datenschutz  ·  Impressum  







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

Benutzen von Klassen aus einer DLL

Ein Thema von moelski · begonnen am 14. Sep 2010 · letzter Beitrag vom 14. Sep 2010
Antwort Antwort
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#1

Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 05:54
Moin !

Haut mich nicht gleich aber ich habe da was im Netz gefunden und wollte euch mal um eure Meinung bitten.
http://entwickler-forum.de/showthread.php?t=24504

Dort schreibt Andreas Kosch:
Zitat:
... in Object Pascal ist es nicht möglich, Variablen oder Klassen aus einer DLL zu exportieren - allerdings ist es zulässig, über eine Schnittstellenprozedur eine Variable oder eine Instanz einer Klasse zu exportieren ...
Ich habe das mal getestet anhand des Beispiels dort. Funktionieren tut es.

Aber ich stell mir schon die Frage was von diesem Konstrukt zu halten ist.
Wie ist da eure Meinung?
Angehängte Dateien
Dateityp: zip ClassDLL.zip (530,9 KB, 25x aufgerufen)
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010

Geändert von moelski (14. Sep 2010 um 06:40 Uhr)
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#2

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 06:39
Moin nochmal,

ich habe die Klasse nochmal erweitert um ein Formular und ein NrComm (serielle Komponente).
Delphi-Quellcode:
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.
Dann habe ich in der anwendung zwei Instanzen erstellt:
Delphi-Quellcode:
  Obj1 := CreateMWStObj;
  Obj1.Comm := nrComm1;
  Obj1.Formular := TTestForm.Create(Self);
  Obj1.Formular.Show;

  Obj2 := CreateMWStObj;
  Obj2.Comm := nrComm2;
Und natürlich in der DLL die Funktion ergänzt.

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
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 07:34
Die Dll hält ja nur die Referenzen. Die eigentliche Funktionalität implementierst du ja im Hauptprogramm
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#4

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 07:51
"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?
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#5

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 08:15
Moin !

Zitat:
Wenn man nun also eine Funktion in der DLL/EXE nutzt, aber im Anderen nicht,
dann enthalten beide RTTIs unterschiedliche VMTs
Nur damit ich das recht verstehe ... Ich definiere eine Klasse mit sagen wir mal 2 Methoden:
Delphi-Quellcode:
function Met1; virtual; abstract;
procedure Met2; virtual; abstract;
Probleme treten dann auf wenn ich diese abstrakte Klasse in der DLL nutze, aber z.B. nur Met1 implementiere und Met2 komplett weg lasse.

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:
Hast du auch an den Shared-MemoryManager gedacht?
Jetzt ja
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#6

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 08:25
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:
function Met1; virtual/overload;
procedure Met2; virtual/overload;
procedure Met3; virtual/overload;
z.B.
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#7

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 08:42
Hmm so ganz bin ich noch nicht bei dir.

Zitat:
Nein, selbst wenn du es implementierst (in der DLL), es dann in der DLL aber nicht benutzt, dann wird dieses vom Compiler wegoptimiert.
Woher will denn der Compiler wissen was er wegoptimieren darf?
Da ich hier eine Klasse implementiere kann er doch erstmal gar nicht wissen was ich später in der EXE davon verwenden werde

Könntest du evtl. das Beispiel prog (Posting 1) mal so umbauen, das es zu der von dir beschriebenen Fehlfunktion kommt?
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#8

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 10:10
Alles, was nicht in diesem Modul (EXE/DLL) verwendet wird, wird nicht mit einkompiliert.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#9

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 10:18
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:
Alles, was nicht in diesem Modul (EXE/DLL) verwendet wird, wird nicht mit einkompiliert.
Mag sein das ich heute morgen aufm Schlauch stehe, aber von den Klassenmethoden wird in der DLL nix genutzt. Müsste das dann nicht wegoptimiert werden
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#10

AW: Benutzen von Klassen aus einer DLL

  Alt 14. Sep 2010, 13:29
Moin !

Je länger ich mit dem DLL Thema rumprobiere, desto mehr komme ich zu dem Entschluss, keine DLLs zu verwenden

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:
  {$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}
Dann könnte man Anwendungen mit unterschiedlichem Funktionsumfang erstellen lassen.

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 !
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Antwort Antwort


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 08:43 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