![]() |
Re: DLL Integration kürzen
Zitat:
Wir hatten auf jeden Fall damals ziemlich seltsame Probleme die sich auch nicht immer reproduzieren liessen. |
Re: DLL Integration kürzen
Das würde mich auch mal interessieren, wo genau da die Knaller sind. Rein intuitiv hätte ich jetzt gesagt, dass außer beim Aufruf dees is-Operators (wie z.B. in Assign oder beim as-operator) und dem Freigeben von Objekten in Modulen, in denen sie nicht erzeugt wurden (GetMem/FreeMem) gar nichts schief gehen kann.
|
Re: DLL Integration kürzen
Zitat:
Der is operator geht aufgrund der unterschiedlichen Orte der RTTI nicht ("Tstringlist ist nicht vom Typ TStringlist" beim TPersistent.Assign). Dem könnte man aber Abhilfe verschaffen wenn man in der Stystem unit den is operator ändert so das er wie der von den InfoPower Komponenten genutzte wwIS funktioniert.... 2. Bpl haben dll gegenüber einen gewaltigen Nachteil. Ich kann in einer BPL keine Programm unit mit einem anderen Schalter kompiliert verwenden so das ich BPL seitig ein anderes Kompilat verwende als in dem Programm. (Gleiche kompiler schalter braucht man bei DLLs ja nur für Objekte die die Seite wechseln, nicht für alles.) |
Re: DLL Integration kürzen
Zitat:
Zitat:
Zitat:
Also, zusammenfassend: mit DLLs funtioniert es nur dann wenn beide beteiligten, also die Applikation und die DLL, die selbe VCL verwenden. Das heisst, dass sie mit Runtime-Packages erzeugt werden müssen (sonst liegen im Speicher später 2 komplette Kopien der VCL rum!). Daraus folgt aber, dass die hier selben Einschränkungen gelten wie für Packages. Warum also nicht direkt Packages verwenden??? Nochmal ganz klar die Frage: Warum sollte jemand auf die Idee kommen für die Arbeit mit Delphi-Typen eine DLL statt einem Package zu verwenden? Man holt sich die Nachteile beider Varianten ohne einen der Vorteile zu haben. Ciao, Ralf |
Re: DLL Integration kürzen
Liste der Anhänge anzeigen (Anzahl: 1)
Quick&Dirty will wohl seinem Namen alle Ehre machen, hmm? :zwinker:
@Alf, Probleme kommen ganz einfach. Du hast eine exportierte Funktion, die eine Referenz vom Typ TStrings nimmt und übergibst ihr natürlich eine Ableitung. Hier kann es ganz schnell fies werden, da die übergebene Referenz ihre Methoden auf einer VMT abbildet, die nicht mit denen der DLL-Version dieser Klasse übereinstimmen. Kurz: Du musst die gleiche Version der benutzten Units haben und die gleiche Version des Compilers. Ergo: Man landet wieder bei Packages, nur ohne die Sicherheit und Einfachheit, die Packages mitbringen. Ein "passt scho'" akzeptiere ich hier nicht. Da kann man gleich VB'ler werden, bei den Honks wäre das eine akzeptable Einstellung, aber deshalb sind diese Honks auch nur VB'ler und keine Entwickler. ;-) Ich predige hier schon lange wiederholt eine einfache und sehr elegante Möglichkeit um Objekte in DLLs benutzen zu können, ohne sich sinnlos an eine RTL- oder Delphiversion zu fesseln: Interfaces. Man kann sich eine einfache Verpackung für einebestehende TSTrings-Referenz bauen, die man problemlos als Interface an eine Delphi/FPC- -DLL schicken kann (auch C++, wenn WideString anstatt AnsiString benutzt wird).
Delphi-Quellcode:
type
ISharedStringList = interface ['{3F5E3362-121A-4EC4-B399-9F8CD321FC34}'] procedure Clear; stdcall; function GetCount : Integer; stdcall; function Add(const aValue : String) : Integer; stdcall; procedure Delete(aIndex : Integer); stdcall; procedure Exchange(aIndex1, aIndex2 : Integer); stdcall; function IndexOf(const aValue : string) : Integer; stdcall; procedure Insert(aIndex : Integer; const aValue : string); stdcall; function GetItem(aIndex : Integer) : String; stdcall; procedure SetItem(aIndex : Integer; const aValue : String); stdcall; property Item[aIndex : Integer] : String read GetItem write SetItem; default; end;
Delphi-Quellcode:
uses
Classes, uSharedInterface; type TSharedStringListWrapper = class(TInterfacedObject, ISharedStringList) private fInnerList: TStrings; protected function GetCount: Integer; stdcall; procedure Clear; stdcall; function Add(const aValue: String): Integer; stdcall; procedure Delete(aIndex : Integer); stdcall; procedure Exchange(aIndex1, aIndex2 : Integer); stdcall; function IndexOf(const aValue : String) : Integer; stdcall; procedure Insert(aIndex : Integer; const aValue : String); stdcall; function GetItem(aIndex: Integer): String; stdcall; procedure SetItem(aIndex: Integer; const aValue: String); stdcall; public property InnerList : TStrings read fInnerList; constructor Create(aInnerList : TStrings); class function Wrap(aInnerList : TStrings) : ISharedStringList; end; implementation { TSharedStringListWrapper } function TSharedStringListWrapper.Add(const aValue : String) : Integer; begin result := InnerList.Add(aValue); end; procedure TSharedStringListWrapper.Clear; begin InnerList.Clear(); end; constructor TSharedStringListWrapper.Create(aInnerList : TStrings); begin inherited Create(); fInnerList := aInnerList; end; procedure TSharedStringListWrapper.Delete(aIndex : Integer); begin InnerList.Delete(aIndex); end; procedure TSharedStringListWrapper.Exchange(aIndex1, aIndex2 : Integer); begin InnerList.Exchange(aIndex1, aIndex2); end; function TSharedStringListWrapper.GetCount : Integer; begin result := InnerList.Count; end; function TSharedStringListWrapper.GetItem(aIndex : Integer) : String; begin result := InnerList[aIndex]; end; function TSharedStringListWrapper.IndexOf(const aValue : String) : Integer; begin result := InnerList.IndexOf(aValue); end; procedure TSharedStringListWrapper.Insert(aIndex : Integer; const aValue : String); begin InnerList.Insert(aIndex, aValue); end; procedure TSharedStringListWrapper.SetItem(aIndex : Integer; const aValue : String); begin InnerList[aIndex] := aValue; end; class function TSharedStringListWrapper.Wrap(aInnerList : TStrings) : ISharedStringList; begin result := Create(aInnerList); end;
Delphi-Quellcode:
Die kann man nun immer nehmen, wenn man irgendeine TStrings-Ableitung in einer DLL bearbeiten will.
uses
ShareMem, uSharedInterface in '..\uSharedInterface.pas'; {$R *.res} procedure AddToStringList(const aStringList : ISharedStringList; const aString : String); stdcall; begin aStringList.Add(aString); end; exports AddToStringList; |
Re: DLL Integration kürzen
Zitat:
|
Re: DLL Integration kürzen
Zitat:
Ja, solange du mit den gleichen Versionen von allen Units und RTL arbeitest. Ansonsten liegt an an Position X plötzlich Methode z, während die DLL dort eine Methode y hat. Und genau dieses Problem macht das ganze so absolut unnötig komplex. Versteckte Komplexität wie solche schrecklich engen Abhängigkeiten zwischen Modulen müssen entweder ausführlich dokumentiert werden, oder man nimmt Packages, bei denen diese Abhängigkeit as-designed und somit allgemein bekannt ist. Der Weg, den ich aufgezeigt habe, umgeht diese unnötig enge Kopplung... |
Re: DLL Integration kürzen
Gut, eigentlich ist deine Lösung ja fast identisch mit normalen virtuellen Methoden. Einziger Unterschied ist meiner Meinung nach, dass es bei dem Interface keine verschiedenen Versionen geben wird. Wenn dem aber so wäre, dann könnte selbiges Problem mit unterschiedlichen Methoden an gleichen Offsets auch auftreten.
|
Re: DLL Integration kürzen
Zitat:
Dadurch kann es das nicht geben, außer du verwendest 2 unterschiedliche Versionen eines Interfaces mit der gleichen GUID. Das wäre ganz böse, bei Erweiterungen lieber vom alten Interface ableiten und ein neues mit neuer GUID deklarieren. Die Implementierung implementiert dann einfach beide (ist ja kein Extraaufwand). Dadurch bleiben DLLs kompatibel, auch wenn sie gegen eine ältere Version deiner PlugIn API gebaut wurden. |
Re: DLL Integration kürzen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:33 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