![]() |
DLL - Objekte austauschen
Hallo,
Ich weiß, dass Objekte zwischen Anwendung und DLL eigentlich nur per Interface geshared werden können/dürfen/sollen. Folgende Situation:
Delphi-Quellcode:
Meine Anwendung erstellt nun ein TFoobarKapselung und gibt es der DLL in Form eines IFoobarKapselung.
TFoobar = class;
IFoobarKapselung = interface ['{B88AB8F5-1087-4496-84FA-54A37867DD47}'] function _Instance: Pointer; // ... end TFoobarKapselung = class(TInterfacedObject, IFoobarKapselung) FFooBar: TFoobar; function _Instance: Pointer; // Gibt FFooBar zurück (bitte nicht hauen!) // .. end; Die DLL benutzt das Object zu 90% auch indem es auf die Methoden des IFoobarKapselung-Interfaces zugreift. Soweit so gut (erst mal). In der DLL wird aber eine Bibliothek benutzt, die eine TFoobar-Instanz benötigt. Diese Bibliothek weiß natürlich nichts von meinem Interface (und will auch nichts davon wissen). Von daher bleibt mir nichts anderes übrig als es so zu machen:
Delphi-Quellcode:
FastMM4 hat sich zuerst beschwert dass Speicher der in der Anwendung reserviert wird in der DLL freigegeben wird.
//
TBibliothekObj.Create(TFoobar(FoobarIntf._Instance)) Meine super tolle Idee war der DLL den MemoryManager der Anwendung zu übergeben. (GetMemoryManager (Anwendung)/SetMemoryManager (In der DLL)). Das schien im ersten Moment sogar zu funktionieren, aber jetzt habe ich wieder eine Zugriffsverletzung bei der ich ziemlich sicher bin, dass diese durch die übergebenen Objektinstanzen (und folgender Speicherkorruption) verursacht wurden. Daher habe ich, weise wie ich bin :mrgreen: beschlossen, dass ich ich auf dem Holzweg bin. ============================= Jetzt ist die Frage: Wie löse ich das Problem? Ich kann die Bibliothek nicht ändern - die erwartet ein TFoobar. Aber ich kann der DLL nur ein Interface geben.. Das muss doch irgendwie lösbar sein... Hat jemand eine Idee, ein Workaround, ein Pattern, ein Irgendwas? :( |
AW: DLL - Objekte austauschen
Kannst du eine Ableitung von TFooBar machen, die als ein Wrapper über das Interface fungiert? Das geht natürlich nur, wenn TFooBar ausreichend virtuelle Methoden bereitstellt.
Der offiziell empfohlene Weg wäre, die DLL in eine BPL umzuwandeln. |
AW: DLL - Objekte austauschen
Ich könnte TFooBar ableiten, aber sofern ich jetzt nicht irgendwas verpasse bringt mir das nicht wirklich was.
Der Konstruktor des Bibliotheks-Objekts will ja trotzdem ein TFooBar und kein Interface. Selbst wenn ich ein
Delphi-Quellcode:
hätte, bräuchte ich ja trotzdem eine Objektinstanz um sie der Bibliothek zu übergeben:
//
TMeinFooBar = class(TFooBar, IFoobarKapselung)
Delphi-Quellcode:
Oder habe ich dich falsch verstanden?
// Anwendung
var foobar: TFooBar; kapselung: IFoobarKapselung; begin foobar := TFoobar.Create; kapselung := TFoobarKapselung.Create(foobar); DoDLLStuff(kapselung); // DLL procedure DoDLLStuff(const fooBar: IFoobarKapselung); var bib: TBibliotheksObject; begin bib := TBibliotheksObject.Create(TFooBar(foobar._Instance)); // Ich kann ja "foobar" nicht übergeben.. egal ob dahinter ein TFoobar oder ein TMeinFoobar = class(TFoobar) hängt end; // Bibliothek: TBibliotheksObject = class public constructor Create(AFoobar: TFoobar); end; |
AW: DLL - Objekte austauschen
Ich nehme an, das eigentliche in der DLL gebrauchte TFooBar-Objekt kann nicht so einfach in der DLL neu erzeugt werden und mit den Werten aus dem geinterfacten Fassade-Objekt gefüllt werden?
|
AW: DLL - Objekte austauschen
Zitat:
TFooBar ist eine Datenbank-Connection. |
AW: DLL - Objekte austauschen
Zitat:
Beispiel:
Delphi-Quellcode:
Innerhalb der DLL erzeugst du dann ein TFoobarWrapper mit dem Interface im Create und den Wrapper übergibst du dann an die Bibliothek. Geht halt nur, wenn TFoobar ausreichend virtuelle Methoden hat.
type
TFoobar = class public procedure MyMethod; virtual; end; IFoobar = interface procedure MyMethod; end; TFoobarWrapper = class(TFoobar) private FInterface: IFoobar; public constructor Create(AInterface: IFoobar); procedure MyMethod; override; end; constructor TFoobarWrapper.Create(AInterface: IFoobar); begin inherited Create; FInterface := AInterface; end; procedure TFoobarWrapper.MyMethod; begin FInterface.MyMethod; end; Wenn, wie gesagt, TFoobar eine Datenbank-Connection ist, dann sag doch mal, welche. Eventuell kann man dann konkretere Aussagen treffen. |
AW: DLL - Objekte austauschen
Die Connection ist eine (abgeleitete) TIBCConnection (IBDAC) (Firebird 3.0)
|
AW: DLL - Objekte austauschen
Wenn du DLL und EXE mit runtime Bibliotheken übersetzt, dann kannst du ohne Probleme Objekte sharen. Nur sollten exe und DLL mit der gleichen Delphi Version übersetzt worden sein
|
AW: DLL - Objekte austauschen
Es muss leider eine DLL sein
|
AW: DLL - Objekte austauschen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:48 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