Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DLL Integration kürzen (https://www.delphipraxis.net/101360-dll-integration-kuerzen.html)

hedie 11. Okt 2007 23:21


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';

sirius 12. Okt 2007 08:46

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

Bernhard Geyer 12. Okt 2007 08:48

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)

QuickAndDirty 12. Okt 2007 09:08

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.

Luckie 12. Okt 2007 09:19

Re: DLL Integration kürzen
 
Zitat:

Zitat von QuickAndDirty
@sirius
Man kann Stringlisten hin und her übergaeben dank dem Sharemem.

Ich bin mir ziemlich sicher, dass unser Stern am Nachthimmel das weiß. ;) Er hat ja selber auf Sharemem hingewiesen.

hedie 12. Okt 2007 11:51

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

Ralf Kaiser 12. Okt 2007 15:08

Re: DLL Integration kürzen
 
Zitat:

Zitat von QuickAndDirty
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.

Also das geht definitiv nicht!

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

Apollonius 12. Okt 2007 15:26

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.

Ralf Kaiser 12. Okt 2007 18:34

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
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.

Schon beim "Austausch" von simplen TObjects kann es gehörig knallen! Glaub mir. Wir haben in der Firma darum eine Projektgruppe mit 47 Projekten komplett von DLLs auf Packages umgestellt. Wie gesagt es kann eine ganze Zeit lang gut gehen aber dann können plötzlich vollkommen unreproduzierbare Fehler auftauchen.

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.

Bernhard Geyer 12. Okt 2007 18:43

Re: DLL Integration kürzen
 
Zitat:

Zitat von Alfi001
Schon beim "Austausch" von simplen TObjects kann es gehörig knallen!

Kann ich nur zustimmen. Entweder Packages oder reine C-Kompatible Schnittstelle oder COM/Automation oder Pluginframework wie Hydra.

Ralf Kaiser 12. Okt 2007 18:53

Re: DLL Integration kürzen
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von Alfi001
Schon beim "Austausch" von simplen TObjects kann es gehörig knallen!

Kann ich nur zustimmen. Entweder Packages oder reine C-Kompatible Schnittstelle oder COM/Automation oder Pluginframework wie Hydra.

Was ich nie verstanden wirklich habe: Warum geht so etwas in manchen Fällen gut??? Knallt es erst wenn Teile des Speichers von Windows ausgelagert werden?

Wir hatten auf jeden Fall damals ziemlich seltsame Probleme die sich auch nicht immer reproduzieren liessen.

Apollonius 12. Okt 2007 19:08

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.

QuickAndDirty 14. Okt 2007 10:05

Re: DLL Integration kürzen
 
Zitat:

Zitat von Alfi001
Zitat:

Zitat von QuickAndDirty
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.

Also das geht definitiv nicht!

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

1. können sich die VMTs der DLL und des Programms nicht "ins gehege kommen" das ist einfach quatsch. Habs viele hundert mal so gemacht ist ein Absolut zuverlässiges verfahren wenn man einige Dinge beachtet. Die units die Objecte hin und her reichen müssen mit den selben Schaltern und Optionen kompiliert sein. Objekte die im Programm erschaffen werden sind auch dort zu zerstören und umgekehrt das selbe.
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.)

Ralf Kaiser 14. Okt 2007 10:39

Re: DLL Integration kürzen
 
Zitat:

Zitat von QuickAndDirty
1. können sich die VMTs der DLL und des Programms nicht "ins gehege kommen" das ist einfach quatsch. Habs viele hundert mal so gemacht ist ein Absolut zuverlässiges verfahren wenn man einige Dinge beachtet. Die units die Objecte hin und her reichen müssen mit den selben Schaltern und Optionen kompiliert sein. Objekte die im Programm erschaffen werden sind auch dort zu zerstören und umgekehrt das selbe.

Das mit dem "ins Gehege kommen" war wohl etwas unglücklich formuliert. Es ist aber so, dass die Typeninformationen der beiden TStringlist-Versionen in unterschiedlichen Datensegmenten liegen. Und das kann bei manchen Operationen zu extremen Problemen führen.

Zitat:

Zitat von QuickAndDirty
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....

Ähm, wir sprachen hier aber nicht von einer geänderten System Unit (wer macht denn so was???) sondern von normalem ungepatchten Delphi.

Zitat:

Zitat von QuickAndDirty
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.)

Diese Behauotung verstehe ich nun absolut nicht. Wie willst du denn in der DLL andere Compilerschalter nur für die auszutauschenden Objekte verwenden? Die Einstellungen müssen, genau wie bei dem Package global übereinstimmen.

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

Elvis 14. Okt 2007 11:49

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:
uses
  ShareMem,
  uSharedInterface in '..\uSharedInterface.pas';

{$R *.res}

procedure AddToStringList(const aStringList : ISharedStringList; const aString : String); stdcall;
begin
  aStringList.Add(aString);
end;

exports
  AddToStringList;
Die kann man nun immer nehmen, wenn man irgendeine TStrings-Ableitung in einer DLL bearbeiten will.

Apollonius 14. Okt 2007 11:54

Re: DLL Integration kürzen
 
Zitat:

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.
Das verstehe ich jetzt nicht. Wichtig ist doch nur, dass das Format der VMTs identisch ist, und das ist doch gegeben. Dass die VMTs unterschiedlich sind, ist doch egal, solange immernoch an Offset x Methode y steht.

Elvis 14. Okt 2007 11:58

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
Zitat:

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.
Das verstehe ich jetzt nicht. Wichtig ist doch nur, dass das Format der VMTs identisch ist, und das ist doch gegeben. Dass die VMTs unterschiedlich sind, ist doch egal, solange immernoch an Offset x Methode y steht.

Hatte ich wohl nur kurz angerissen...
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...

Apollonius 14. Okt 2007 12:03

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.

Elvis 14. Okt 2007 12:11

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
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.

Interfaces haben eine standardisierte Art um Methoden aufzurufen (Darauf basiert schließlich COM ;-).
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.

Apollonius 14. Okt 2007 12:17

Re: DLL Integration kürzen
 
Zitat:

Interfaces haben eine standardisierte Art um Methoden aufzurufen
??? Interfaces verwenden standardmäßig doch auch nur eine VMT (Variants mit Interfaces drin sind eine andere Geschichte).

Elvis 14. Okt 2007 12:22

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
Zitat:

Interfaces haben eine standardisierte Art um Methoden aufzurufen
??? Interfaces verwenden standardmäßig doch auch nur eine VMT (Variants mit Interfaces drin sind eine andere Geschichte).

Du hast eine VMT pro Interface pro Instanz. Aber das ist nicht der Punkt.
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. :-)

Apollonius 14. Okt 2007 12:25

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.
Der Punkt ist, dass eine Klasse, die auf die gleiche Art deklariert wird, immer auch die gleichen Methoden an den gleichen Slots haben wird, sofern, was auch für Interfaces gilt, auch die Vorfahren gleich deklariert wurden.

Elvis 14. Okt 2007 12:32

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
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.
Der Punkt ist, dass eine Klasse, die auf die gleiche Art deklariert wird, immer auch die gleichen Methoden an den gleichen Slots haben wird, sofern, was auch für Interfaces gilt, auch die Vorfahren gleich deklariert wurden.

Nein, das ist nirgends standardisiert und kann sich mit jeder Compilerversion ändern. (Hat es IMO auch)
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? ;-)

Apollonius 14. Okt 2007 12:37

Re: DLL Integration kürzen
 
Zitat:

Außerdem reicht ein weiteres Feld vor dem letzten um alles über den Haufen zu werfen.
Was haben denn Felder mit der VMT zu tun?
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?

Elvis 14. Okt 2007 12:42

Re: DLL Integration kürzen
 
Zitat:

Zitat von Apollonius
Zitat:

Außerdem reicht ein weiteres Feld vor dem letzten um alles über den Haufen zu werfen.
Was haben denn Felder mit der VMT zu tun?

Nichts, aber es ging nicht nur um ein Problem. Es geht darum, dass Klassen keine Versionierung erlauben und dass Klassen nicht unabhängig vom Compiler sind.
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? ;-)

Ralf Kaiser 14. Okt 2007 14:10

Re: DLL Integration kürzen
 
Zitat:

Zitat von Elvis
Quick&Dirty will wohl seinem Namen alle Ehre machen, hmm? :zwinker:
.

Sieht ganz so aus... :)

Zitat:

Zitat von Elvis
@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.

Ja! Ich stimme voll und ganz mit dir überein (ich war es nicht, der die Originalfrage gestellt hat, ich habe versucht genau diese Tatsache zu begründen!)

Zitat:

Zitat von Elvis
Ein "passt scho'" akzeptiere ich hier nicht.

Auch hier volle Zustimmung von mir!

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:

Zitat von Elvis
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).

... Code gelöscht (siehe Originalpost) ...

Das ist wirklich eine sehr interessante Möglichkeit, vor allem im Hinblick auf die Verwendung von Delphi-Objekten in anderen Sprachen. Muss ich mir mal merken. Danke für den Tipp!

Ciao,
Ralf

QuickAndDirty 16. Okt 2007 09:58

Re: DLL Integration kürzen
 
Zitat:

Zitat von Alfi001
Das mit dem "ins Gehege kommen" war wohl etwas unglücklich formuliert. Es ist aber so, dass die Typeninformationen der beiden TStringlist-Versionen in unterschiedlichen Datensegmenten liegen. Und das kann bei manchen Operationen zu extremen Problemen führen.

Im Falle der Stringliste kann ich sie dir benennen. Es ist genau eine: TStringlist.assign(Bla:tpersistent)


Zitat:

Zitat von Alfi001
Ähm, wir sprachen hier aber nicht von einer geänderten System Unit (wer macht denn so was???) sondern von normalem ungepatchten Delphi.

Schon klar, mir viel nur ein das ich mal versucht hab das Problem komplett aus der Welt zu schaffen, und das hat sogar Funktioniert nur ist es ne dumme Sache solche Patches immer wieder durchzuführen wenn ne neu Delphi Version rauskommt.
Und für die meisten Sachen gibts ja Interfaces...die sind sowieso viel schöner und sauberer.


Zitat:

Zitat von Alfi001
Diese Behauotung verstehe ich nun absolut nicht. Wie willst du denn in der DLL andere Compilerschalter nur für die auszutauschenden Objekte verwenden? Die Einstellungen müssen, genau wie bei dem Package global übereinstimmen.

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???

Dies gilt nur für die VCL. Wenn ich z.b. auf beiden Seiten Bibliotheken mit unterschiedlichen kompiler schaltern verwende, dies aber nicht übergreifend, dann macht das durchaus Sinn. Und das wirst du mit einer BPL nie hin kriegen.



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.

Ralf Kaiser 16. Okt 2007 18:07

Re: DLL Integration kürzen
 
Zitat:

Zitat von QuickAndDirty

Hi,

Zitat:

Zitat von Alfi001
Ähm, wir sprachen hier aber nicht von einer geänderten System Unit (wer macht denn so was???) sondern von normalem ungepatchten Delphi.

Schon klar, mir viel nur ein das ich mal versucht hab das Problem komplett aus der Welt zu schaffen, und das hat sogar Funktioniert nur ist es ne dumme Sache solche Patches immer wieder durchzuführen wenn ne neu Delphi Version rauskommt.
Und für die meisten Sachen gibts ja Interfaces...die sind sowieso viel schöner und sauberer.

Ich reagiere auf solche Patches immer extrem allergisch. Als ich in der Firma anfing in der ich jetzt noch arbeite habe ich ein paar Projekte von einem Vorgänger übernommen der nicht mehr verfügbar war (ich konnte ihn also nichts fragen). Dieser Mensch hatte, weil er es nicht besser wusste einfach einige Teile der VCL (damals noch D1) gepatcht und dies nirgendwo dokumentiert.

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!!

QuickAndDirty 19. Okt 2007 09:25

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