AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Integration kürzen

Ein Thema von hedie · begonnen am 11. Okt 2007 · letzter Beitrag vom 19. Okt 2007
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Ralf Kaiser
Ralf Kaiser

Registriert seit: 21. Mär 2005
Ort: Wuppertal
932 Beiträge
 
Delphi 10.3 Rio
 
#11

Re: DLL Integration kürzen

  Alt 12. Okt 2007, 17:53
Zitat von Bernhard Geyer:
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.
Ralf Kaiser
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#12

Re: DLL Integration kürzen

  Alt 12. Okt 2007, 18:08
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.882 Beiträge
 
Delphi 12 Athens
 
#13

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 09:05
Zitat von Alfi001:
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.)
Andreas
Monads? Wtf are Monads?
  Mit Zitat antworten Zitat
Benutzerbild von Ralf Kaiser
Ralf Kaiser

Registriert seit: 21. Mär 2005
Ort: Wuppertal
932 Beiträge
 
Delphi 10.3 Rio
 
#14

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 09:39
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 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 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
Ralf Kaiser
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#15

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 10:49
Quick&Dirty will wohl seinem Namen alle Ehre machen, hmm?

@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.
Miniaturansicht angehängter Grafiken
screenie_1_469.png  
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#16

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 10:54
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#17

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 10:58
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...
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#18

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 11:03
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#19

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 11:11
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.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#20

Re: DLL Integration kürzen

  Alt 14. Okt 2007, 11:17
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).
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz