![]() |
DLL Integration kürzen
Hallo
Durch diese vielen externals verursacht mein Programm bei start während 3 Sekunden 90% Systemauslastung Gibts ne möglichkeit das zu Minimieren? Und isses möglich den Code zu kürzen in dem man gleiche dll verlinkungen zusammen fasst? danke schonmal
Delphi-Quellcode:
procedure addtemp(filename:string);stdcall;
external 'db_main.dll'; function savedbvideo(dbcount:Integer;Titel,Lenght,Bitrate,path:tstrings):boolean;stdcall; external 'db_main.dll'; function additem(Name,Path,Interpret:string):boolean;stdcall; external 'db_main.dll'; function savedb(dbcount:Integer;Name,Path,Interpret:tstrings):boolean;stdcall; external 'db_main.dll'; function inifnset(Filename :String):integer;stdcall; external 'db_main.dll'; function ID3(Filename:string):Tstrings;stdcall; external 'ax_main.dll'; function listdbn():tstringlist;stdcall; external 'db_main.dll'; function listdbp():tstringlist;stdcall; external 'db_main.dll'; function listdbi():tstringlist;stdcall; external 'db_main.dll'; procedure omp(filename:string);stdcall; external 'ax_main.dll'; function mpeg(Filename:string):Tstrings;stdcall; external 'ax_main.dll'; function additemvideo(Titel,Lenght,Bitrate,path:string):boolean;stdcall; external 'db_main.dll'; function inifnsetvideo(Filename :String):integer;stdcall; external 'db_main.dll'; function listdbvt():tstringlist;stdcall; external 'db_main.dll'; function listdbvl():tstringlist;stdcall; external 'db_main.dll'; function listdbvb():tstringlist;stdcall; external 'db_main.dll'; function listdbvp():tstringlist;stdcall; external 'db_main.dll'; function saveid3(descriptions:tstrings):boolean;stdcall; external 'ax_main.dll'; function updsection(section:integer;setings:tstrings):boolean;stdcall; external 'db_main.dll'; function listdbb():tstringlist;stdcall; external 'db_main.dll'; |
Re: DLL Integration kürzen
1. Zusammenfassen? Nicht das ich wüsste.
2. Was stört dich an einer kurzen Systemauslastung von 90%, wenn nun mal 3 DLLs geladen werden müssen. Vielleicht solltest du überlegen, ob du in den DLLs nicht auf RTL (bzw. auch noch VCL) verzichten kannst, damit die DLLs kleiner werden. Aber bis jetzt hast du ja sogar noch 10% Reserve. 3. Als Rückgabewert eine TStringlist? Wie geht denn das? Und falls dies mit Sharemem funktionieren sollte, muss ja auch noch die Sharemem geladen werden, keine Ahnung wieviel System-Ressourcen das benötigt. Sowas versuche ich lieber zu umgehen. 4. Alternativ kannst du die DLLs auch dynamisch laden: - LoadLibrary und FreeLibrary - und dazu GetProcAddress |
Re: DLL Integration kürzen
Ich glaube nicht das es die Anzahl der hart gebundenen Funktionen sind. Ich würde tippen diese benötigen für 0.0001 Sekunden 100% Rechenzeit. Die Bremse liegt woanders (z.B. was schon sirius angeführt hat)
|
Re: DLL Integration kürzen
@sirius
Man kann Stringlisten hin und her übergaeben dank dem Sharemem. Was nicht geht ist der Is operator also auch nicht assign, auf der falschen Seite. Assign wäre mit zum Teil durch clear; AddStrings(bla); ersetzbar. @Threadsteller: Versuch sie wie vorgeschlagen dynamisch ein zu binden. und Teste das doch mal mit DLLs die nur leere Funktionen zu verfügung stellen und sonst keine Rescourcen nutzen. Vielleicht liegt das "Problem" ja in einer der DLLs. |
Re: DLL Integration kürzen
Zitat:
|
Re: DLL Integration kürzen
Danke für die Antworten
Ja ShareMem wird verwendet... Im bereich VCL und RTL bin ich noch ein wenig neu. Was genau ist die VCL bei einer DLL und die RTL? Und wie kann man die Weglassen? danke schonmal |
Re: DLL Integration kürzen
Zitat:
Die aufrufende Applikation und die DLL haben verwalten unterschiedliche Versionen der RTL! Das bedeutet Applikation.TStringList <> DLL.TStringList. Du weist ja selbst daruaf hin, dass der IS Operator nicht funktioniert (Warum ist das wohl so). Wenn das bisher bei dir funktioniert hat dann hast du wahrscheinlich irgendwie Glück gehabt, dass sich im Speicher die VMTs nicht ins Gehege gekommen sind. Das kann aber irgendwann mal gewaltig knallen! (Also machs besser nicht) Um Delphi-spezifische Klassen zwischen DLLs und Applikationen auszutauschen wurden extra die Packes erfunden! Das sind DLLs (die nur eine andere Endung haben) bei denen sichergestellt ist, dass Applikation und DLL die selbe Version der RTL verwenden. Ciao, Ralf |
Re: DLL Integration kürzen
Nein. Clear und AddStrings funktionieren wunderbar. Warum auch nicht? Es werden nur Strings und TObjects ausgetauscht, da wird keine RTTI benötigt und auch kein Klassentypvergleich.
|
Re: DLL Integration kürzen
Zitat:
Wenn nur Strings ausgetauscht werden ist das, Dank ShareMem, kein Problem aber es war ja die Rede von DLL-Routinen die TStringList-Instanzen zurückliefern und das rennt eben irgendwann ganz gehörig vor die Wand. Sobald irgendetwas von TObject abwärts ins Spiel kommt sind Packages angesagt. |
Re: DLL Integration kürzen
Zitat:
|
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:
|
Re: DLL Integration kürzen
Zitat:
Der Punkt ist, dass ein Interface, das auf die gleiche Art deklariert wird, immer auch die gleichen Methoden an den gleichen Slots haben wird. Das ist eine Vorraussetzung von COM, und wir können es hier als eine Art compiler- & modul-übergreifendes Esperanto für Objekte benutzen. :-) |
Re: DLL Integration kürzen
Zitat:
|
Re: DLL Integration kürzen
Zitat:
Außerdem reicht ein weiteres Feld vor dem letzten um alles über den Haufen zu werfen. Klassen = Intramodulobjekte, mit der Ausnahme von Packages oder gemeinsam verwendeten Runtimepackages. Interfaces = Intermodul- & Intercompilerobjekte Klassen für letzteres zu benutzen ist wie Polymorphie mit Vanilla-C, möglich aber krank. Nicht zu vergessen es ist eine echte Bitch sowas zu dokumentieren. Unsere Zunft produziert auch dann noch so schlechte Qualität, dass es beschämend ist, wenn man sich an alle Regeln und Good-Practices hält. Warum es unnötig noch weiter herausfordern, hmm? ;-) |
Re: DLL Integration kürzen
Zitat:
Und ich dachte immer, dass der Compiler einfach die erste virtuelle Methode an VMT-Slot 1 setzt, die zweite an Slot 2, usw. - bei Klassen wie bei Interfaces. Wie war das denn vor jenen Änderungen? |
Re: DLL Integration kürzen
Zitat:
Du hast dich ein wenig zu sehr auf das eine Beispiel eingeschossen, was ich oben erwähnt habe. ;-) btw: Meine DLL in dem Bleistift oben ist 17KB groß. Wie große wäre sie gewesen, wenn ich dort tatsächlich ein TStrings benutzt hätte? 300 KB, 400? ;-) |
Re: DLL Integration kürzen
Zitat:
Zitat:
Zitat:
Selbst wenn jemand auf die Idee käme ein "passt scho'" zu akzeptieren wird er damit eben irgendwann ganzgehörig auf die Nase fallen und dann nicht mehr wissen warum (solche selbstgeschaffenen "Fehler" sind nicht so einfach zu finden) Zitat:
Ciao, Ralf |
Re: DLL Integration kürzen
Zitat:
Zitat:
Und für die meisten Sachen gibts ja Interfaces...die sind sowieso viel schöner und sauberer. Zitat:
Zu deiner Frage also eigentlich sollte er ein Package verwenden...ausser es liegt ein Szenario vor in dem einige ausgewählte Units mit unterschiedlichen Kompilerschaltern genutzt werden müssen.... Ein Package ist auf jeden Fall sauberer wenn man sein Projekt von Grund auf so plant. Wenn er ne größere Sache umstellt kann es durchaus sein das eine DLL und ein paar schmutzige Tricks vorzuziehen sind. @Elvis: Quick and Dirty is an Art , isn't it? Ausserdem ist es kosteneffektiv und Arbeistplatz sichernd, wenn nur du weist warum das TROTZDEM geht. Zugegeben es ist nicht schön.... Ausserdem ist der von Delphi mitgelieferte IS Operator so ziemlich das langsamste was es in dieser Richtung geben kann, Wenn man mal das Verfahren der Infopower leute nimmt geht einiges wesentlich schneller!!! Performance ist ja leider seit Dotnet nicht mehr in Mode. |
Re: DLL Integration kürzen
Zitat:
Solange man die Projekte auf seinem Ex-Rechner kompillierte funktionierte alles tadellos. Nur auf meinem Rechner wollten einige Sachen einfach nicht klappen was logisch war, hatte ich doch ein frisch installiertes System. So entwickelt man gegen solche Praktiken schnell eine extreme Allergie!! |
Re: DLL Integration kürzen
@Algi001:
Ich dich kann ich verstehen. Es war auch mehr ein experimenteller Patch, nur um zu sehen ob das geht, hab dabei viel gelernt. Im Übrigen sind VCL Patches durchaus sinnvoll du solltest da keine allergischen Reaktionen ausbilden. In unserer Firma wurde z.B. die DBtables von D3 bis D7 immer gepatched, weil es scheinbar nicht möglich war das die Borländer einen Bug beseitigten, der in seltenen Fällen auftrat. Da wir "leider"(!!!) sehr viele Toolbibliotheken verwenden ist bei uns das Einrichten einer Arbeitsumgebung sowieso auf mehreren Seiten Dokumentiert. Es dauert 1-2 Tage um eine Arbeitsplatz einzurichten, deswegen machen wir alles auf VMs. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 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 by Thomas Breitkreuz