Autor Beitrag
Billi Berserker
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 44



BeitragVerfasst: Mo 19.03.07 21:57 
Ich hab kein direktes Problem sondern nur eine kleine Grundsatzfrage...

Große Daten und insbesondere Klassen zwischen Anwendung und einer geladenen Dll austauschen ist immer so eine Sache da die Daten ja im Speicherbereich der Anwendung bzw. Dll erzeugt werden und soweit ich weiß ja die Dll z.b. nicht so einfach auf den Speicherbereich der Anwendung zugreifen kann. D.h. erzeuge ich in der Anwendung eine Klasse und übergebe den Pointer darauf an die Dll dann gibts ne lustige Zugriffsverletzung wenn die Dll versucht darauf zuzugreifen. (liege ich damit soweit richtig?)

Die sache ist nun das bei mir Anwendung und Dll Dateien alle mit benutzung der RTL und VCL runtime packages compiliert werden. Der Effekt davon ist das ich in der Anwendung eine Klasse erzeuge (z.b nen XML Parser, TJvSimpleXML) diese an die Dll geben kann und dann Dll und Anwendung mit der selben Instanz der Klasse arbeiten. Es gibt durch benutzung der runtime packages keine Zugriffsverletzung wenn die Dll versucht die in der Anwendung erzeuge Klasse direkt zu verwenden.

Nur kommt mir das ganze irgendwie sehr seltsam vor, es funktioniert zwar ohne Probleme - aber is das wirklich so gedacht? oder nur ein dummer Nebeneffekt? oder sollte das eh immer gehen (auch ohne runtime packages)?
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Mo 19.03.07 22:09 
Eine BPL-Datei ist nichts anderes als eine DLL. Das bringt den Vorteil für dich, dass alle DLLs in Deinem Projekt auf die gleiche Kopie zugreifen und somit auch Daten geshared werden.

Einfaches beispiel : TApplication-Object

Compilierst Du deine Anwendung und Deine DLLs ohne Laufzeit-Bibliotheken (also VCL, RTL direkt jeweils mit reingelinkt), hat die globalen Variable "Application" in jeder DLL und der Anwendung einen anderen Wert, da jeder seine eigene Kopie hat.

Sagst Du in den Optionen allerdings "build with runtime packages", dann wird von allen die gleiche Kopie benutzt und der Wert in Application ist für alle gleich.

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Billi Berserker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 44



BeitragVerfasst: Di 20.03.07 00:13 
Ok gut danke :)
War nur durch zufall drauf gestoßen als eine Dll mal nicht mit runtime packages compiliert hab und plötzlich nix mehr ging ;)
Ist im Endeffekt dann sogar ziemlich praktisch weils alles einfacher macht.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 23.03.07 23:40 
Windows ist es eigentlich egal, von wo auf die Daten zugegriffen wird, solange die Zeiger auf die Daten korrekt sind.

Das Problem liegt also, wenn man korrete Zeiger übergibt, nicht an Windows, sondern an den bereits erwähnten Code-Dopplungen.

Wenn man weiß, was man macht, kann man natürlich auch Daten zwischen der Anwendung und der DLL direkt übergebn (sollte dann aber sichergehen, dass beide die gleiche Version der Unit nutzen), muss aber damit leben, dass bestimmte Dinge nicht, bzw nur relativ aufwändig realisiert werden können.

Vorteilhafter ist es aber allgemein, wenn man im Kontext der Plugin-Programmierung bzw. dem Datenaustausch zwischen Anwendung und DLL ganz auf OOP verzichtet und nur im eigenen Bereich (also nur anwendungsintern und\oder nur DLL-intern) mit OOP arbeitet und für den Austausch zwischen beiden Teilen statische Strukturen (Records, Arrays) verwendet und ggf. der DLL eine Pointer-Tabelle mit Zeigern auf Funktionen der Hauptanwendung bereitstellt, die verwendet werden können.

Dies hat zwar den kleinen Nachteil, dass ein paar Vorzüge von Delphi flöten gehen, aber den großen Vorteil, dass man auch mit anderen Programmiersprachen relativ problemlos Erweiterungen für die Anwendung schreiben kann.

Ferner ein Tipp am Rande: Es empfiehlt sich, bei Anwendungen, die Plugins nutzen sollen, einen Memory-Manager wie FastMM4 zu verwenden, da dieser innerhalb der DLL automatisch den Speichermanager der Hauptanwendung übernimmt. Damit gehen dann neben Records und statischen Arrays auch Operationen wie String-Manipulation, Dyn. Arrays und das Verwalten von Speicherblöcken die zwischen Anwendung und DLL geshared werden wesentlich Reibungsloser. Ist ein MM geladen, der dies nicht kann (z.B. BorMM oder ShareMem), dürfen Speicherblöcke nur in dem Anwendungsteil freigegeben werden, in dem diese auch reserviert wurden.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.