AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Plugins: Datenaustausch zwischen DLL und Hauptprogramm
Thema durchsuchen
Ansicht
Themen-Optionen

Plugins: Datenaustausch zwischen DLL und Hauptprogramm

Ein Thema von alleinherrscher · begonnen am 20. Okt 2009 · letzter Beitrag vom 27. Nov 2009
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#11

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 21. Okt 2009, 15:22
Zitat von himitsu:
Delphi-Quellcode:
procedure TApp.AddStream(aStream: IDelphiStream); stdcall;
begin
  astream.position:=0;
  astream.SaveToFile('C:\test2.jpg');
end;
Das war auch mein erster Versuch. Aber da astream ja vom Typ IDelphiStream ist, besitzt er die Methode SavetoFile gar nicht...

//edit: ich mein...das is nicht sooo schlimm...Hauptsache der Stream kommt an...ich kann ihn ja per Tmemorystream.copyfrom in einen memorystream kopieren, denke ich mal...
//edit2: Naja, auch nicht wirklich, da sogesehen ja IDelphiStream keine Ableitung von TStream ist.
//edit3: Ich bin doof...sorry, dafür hattest du ja extra die auskommentierten Methoden eingefügt im Interface Idelphistream...D.h. da müsste ich dann noch sowas wie Copyfrom mit einbauen...
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#12

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 21. Okt 2009, 15:33
drum sagte ich ja, daß man diese eventuell noch implementieren muß
(hatte es vorhin nur nicht gemacht, da ich alles Vorhandene erstmal nur zusammenkopiert hatte und nichts direkt "neu" schrieb)

Delphi-Quellcode:
type
  IDelphiStreamIntern = interface
    {private}
    function GetPosition: Int64;
    procedure SetPosition(const Pos: Int64);
    procedure SetSize64(const NewSize: Int64);
    function GetSize: Int64;
  end;
  IDelphiStream = interface(IDelphiStreamIntern)
    ['{65805750-623E-4719-AD79-A30FF6FCA3CA}']
    procedure SetSize(NewSize: Longint);
    function Write(const Buffer; Count: Longint): Longint;
    function Read(var Buffer; Count: Longint): Longint;
    function Seek(Offset: Longint; Origin: Word): Longint;
    procedure Clear;
    procedure LoadFromStream(Stream: IDelphiStream);
    procedure SaveToStream(Stream: IDelphiStream);
    procedure LoadFromFile(const FileName: WideString);
    procedure SaveToFile(const FileName: WideString);
    property Position: Int64 read GetPosition write SetPosition;
    property Size: Int64 read GetSize write SetSize64;
  end;

  TInterfacedMemoryStream = class(TMemoryStream, IDelphiStream, IInterface)
  private
    function GetPosition: Int64;
    procedure SetPosition(const Pos: Int64);
    procedure SetSize64(const NewSize: Int64);
  protected
    FRefCount: Integer;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    class function NewInstance: TObject; override;
    property RefCount: Integer read FRefCount;

    procedure LoadFromStream(Stream: IDelphiStream); overload;
    procedure SaveToStream(Stream: IDelphiStream); overload;
    procedure LoadFromFile(const FileName: WideString); overload;
    procedure SaveToFile(const FileName: WideString); overload;
  end;

function TInterfacedMemoryStream.GetPosition: Int64;
begin
  Result := inherited Position;
end;

procedure TInterfacedMemoryStream.SetPosition(const Pos: Int64);
begin
  inherited Position := Pos;
end;

procedure TInterfacedMemoryStream.SetSize64(const NewSize: Int64);
begin
  inherited Size := NewSize;
end;

function TInterfacedMemoryStream.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

function TInterfacedMemoryStream._AddRef: Integer;
begin
  Result := InterlockedIncrement(FRefCount);
end;

function TInterfacedMemoryStream._Release: Integer;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result = 0 then
    Destroy;
end;

procedure TInterfacedMemoryStream.AfterConstruction;
begin
  InterlockedDecrement(FRefCount);
end;

procedure TInterfacedMemoryStream.BeforeDestruction;
begin
  if RefCount <> 0 then
    System.Error(reInvalidPtr);
end;

class function TInterfacedMemoryStream.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  TInterfacedMemoryStream(Result).FRefCount := 1;
end;

procedure TInterfacedMemoryStream.LoadFromStream(Stream: IDelphiStream);
var
  buf: array[0..65535] of Byte;
  i: Integer;
begin
  Clear;
  while true do
  begin
    i := Stream.Read(buf, Length(buf));
    if i = 0 then break;
    if Write(buf, i) <> i then System.Error(reOutOfMemory);
  end;
end;

procedure TInterfacedMemoryStream.SaveToStream(Stream: IDelphiStream);
var
  buf: array[0..65535] of Byte;
  i: Integer;
begin
  Stream.Clear;
  while true do
  begin
    i := Read(buf, Length(buf));
    if i = 0 then break;
    if Stream.Write(buf, i) <> i then System.Error(reOutOfMemory);
  end;
end;

procedure TInterfacedMemoryStream.LoadFromFile(const FileName: WideString);
begin
  inherited LoadFromFile(String(FileName));
end;

procedure TInterfacedMemoryStream.SaveToFile(const FileName: WideString);
begin
  inherited SaveToFile(String(FileName));
end;
LoadFromStream und SaveToStream arbeiten hier intern aber nur mit String, also bis Delphi 2007 mit AnsiString.
Wenn man auch da wirklich den WideString unterstüzen will, dann muß man sich einen Unicode-fähigen FileStream besorgen (also Unicode bei den Dateinamen).

Und direkt AnsiString/UnicodeString geht halt wegen der getrennten Speicherverwaltung nicht so einfach ... stickwort Hier im Forum suchenSharedMemoryManager
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#13

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 21. Okt 2009, 15:43
Klappt perfekt! Entschuldigung, dass ich im letzten Post nicht richtig aufgepasst habe, sonst hätte sich die Frage von selbst geklärt! Großartige Leistung! Ich bedanke mich recht herzlich!
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#14

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 21. Okt 2009, 15:52
bitte bitte

und praktisch genauso, wie es jetzt mit den Stream ging,
macht man es jetzt mit den anderen Interfaces für Plugin und App
(nur daß man hier leicht direkt von TInterfacedObject erben kann und dann die Basis-Interface-Funktionen schon fertig hat)

also der Zugriff dann von außen immer nur über das jeweilige Interface
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
673 Beiträge
 
Delphi 10.4 Sydney
 
#15

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 26. Nov 2009, 15:31
Sorry, wenn ich mich kurz einmische : Man kann sehr gut mit Klassen in DLLs arbeiten ohne die Probleme der verschiedenen RTTI etc zu haben, man muss nur wissen, wie Das Geheimnis sind Laufzeit-Pakete.

Ich habe eine grosse Demo mit Forms / Frames / Objects etc auf meiner Homepage. Die Demo umfasst 9 Plugins als DLL und einer Loader.exe

Einfach mal hier klicken, da gibt es das ganze als rein ausführbaren Code (Delphi2007, wers nicht hat, muss die FULL-version laden, ansonsten die Light) und als nur-source.

Um mit dem Source zu arbeiten, muss man die MAF Components runterladen und installieren, die verwalten unter anderem das ganze plugins-zeugs.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#16

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 26. Nov 2009, 16:09
Bei dieser Variante hat man dann natürlich nur eine RTTI, bezüglich dieser Komponenten ... also die in dem externen Package.

Das ist wie mit dem Speichermanager ... wenn man einen (externen) gemeinsamen Manager nutzt, dann klappt das auch, aber standardmäßig erstmal nicht.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
673 Beiträge
 
Delphi 10.4 Sydney
 
#17

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 26. Nov 2009, 20:48
Auch nur, weil die BPL variante uns von Anfang an zwingt, mit Laufzeit packages zu arbeiten. DLLs tun das nicht
  Mit Zitat antworten Zitat
Elvis

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

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 26. Nov 2009, 22:35
Zitat von MyRealName:
Sorry, wenn ich mich kurz einmische : Man kann sehr gut mit Klassen in DLLs arbeiten ohne die Probleme der verschiedenen RTTI etc zu haben, man muss nur wissen, wie Das Geheimnis sind Laufzeit-Pakete.
Nein.
BPLs taugen eigentlich nur etwas für die IDE, da sie ja schon fest mit einer Version von Compiler, RTL und VCL verheiratet ist.
Für so ziemlich alles andere, bei dem BPLs sinnvoll wären, könnte man auch eine große Single-Exe nehmen ohne irgendwelche Flexibilität zu verlieren.
Warum? Weil BPLs so unflexibel sind, wie es entartete DLLs nur werden können ohne schon Teil der Exe zu sein.

BPLs vorauszusetzen schränkt die Schar von Autoren auf den winzigen Kreis ein, der mit exakt deiner Compiler/VCL/RTL-Version arbeitet und auch ja keine Units/Registrierte Komponentenamen mitbringt, die mit anderen Units/Komponentennamen in dem eng verwobenen Haufen BPLs kollidieren.
Kurz: Es ist fast ausgeschlossen, dass ein anderer aus dir selbst solch ein Plugin schreiben kann ohne zu riskieren, dass es irgendwann explodiert.
Zum Beispiel, weil jmd eine TntControls-Unit in einem seiner Packages hatte, anstatt EXAKT das gleiche Package zu nutzen wie alle anderen.
Aber halt: Niemand schrieb vor welche Version von Komponente XYZ genommen werden muss, weil sich die PlugIns wohl kaum alle gegenseitig die 3rd-Party-Komponenten absprechen können.

Long story short: BPLs sind die grauenvollste, instabilste und zeitverschwenderischte Art sich Flexibilität vorzutäuschen, die ich kenne.
Plugin-Systeme, die auf BPLs aufbauen sind wie Rauchen: Fange nicht damit an, wenn doch höre so schnell wie möglich auf.
Woher ich das weiß? Sagen wir's mal so: "Got the scars to prove it...
Siehe auch hier: http://stackoverflow.com/questions/1...705051#1705051
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
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
673 Beiträge
 
Delphi 10.4 Sydney
 
#19

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 26. Nov 2009, 23:12
Ich weiss nicht, warum Du mir widersprichst, sagst doch nur etwas gegen BPLs und ich rede davon, wie man DLLs nutzen kann mit Klassen drin.
Ich bin kein Fan von BPLs und nutze sie nur für meine Komponenten selbst.
Will man allerdings wirklich modular mit Delphi programmieren, muss man mit Laufzeit-Packages arbeiten (also zumindest die Komponenten-BPLs dynamisch linken).


Das Problem mit den TNTControls kenn ich, hatte ich bei den MAF-Komponenten auch und leider hatte es mir keiner gesagt, so dass der ganze Download für ca. 4-5 Tage fürs Ar--- war, da die version nicht zu nutzen ging.
Ich hatte in meine Komponenten das package PNGComponents eingebunden, da es

1.) kostenlos von der Embarcadero Seite zu beziehen ist
und
2.) man heutzutage nicht mehr auf PNG (wegen Transparenz) in einer App verzichetn sollte/kann

hab dann leidlich durch einen Kunden rausfinden müssen, dass es wirklich nicht geht, dass man meine Komponenten mit einem selbst-erzeugtem PNGComponents package nutzen kann.
Lösung 1 wäre einfach die dcus und BPLs mitzugeben, aber wenn ich mich recht entsinne, ist das Embarcadero nicht so glücklich drüber. Also nahm ich lösung 2 und hab alles schön in Conditional Defines gekapselt, so dass man sie als source-Besizter selbst wieder reinnehmen kann und den nativen support nutzen (TPNGImageList Verwaltung, statt nur TImageList etc).

Allerdings sah ich auch durch mein Test-Programm, das sich neue Versionen von meinen Komponenten bauen konnte und meist auch ohne die Anwendung oder die DLLs zu kompilieren dann auch weiter nutzen. Man muss halt nur aufpassen, dass man keine published properties löscht Oder Methoden umbenennt.

Allerdings ist zu empfehlen, vorhandene Projekte neu zu übersetzen, wenn man ein neues Package baut
  Mit Zitat antworten Zitat
Elvis

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

Re: Plugins: Datenaustausch zwischen DLL und Hauptprogramm

  Alt 27. Nov 2009, 05:52
Zitat von MyRealName:
Ich weiss nicht, warum Du mir widersprichst, sagst doch nur etwas gegen BPLs und ich rede davon, wie man DLLs nutzen kann mit Klassen drin.
Weil ein unschuldiger Mitleser sonst den falschen Eindruck bekäme, dass Pseudo-Modularisierug mit Packages wirkliche Flexibilität bringen würde und einem nicht 70% der Haarpracht kostet.
Zitat:
Will man allerdings wirklich modular mit Delphi programmieren, muss man mit Laufzeit-Packages arbeiten (also zumindest die Komponenten-BPLs dynamisch linken).
Eben nicht. Wirklich modular ist man, wenn die Module nicht so grauenvoll miteinander verzahnt sind sind. Und das heißt, man ist "wirklich modular" wenn man DLLs benutzt und sich in den exportierten Funktionn auf interoperable Typen wie WideString, Integer, double, Interfaces, OleVariant, etc. beschränkt.
Denn dann explodieren Module nicht stets und ständig, weil irgendein Plugin eine neue Unit nutzt, oder wenn man eine neue Delphiversion nutzen will. Ganz zu schweigen davon, dass man dann Plugins mit anderen Sprachen schreiben kann z.B.: FPC, C++, C#,...
Zitat von MyRealName:
Allerdings sah ich auch durch mein Test-Programm, das sich neue Versionen von meinen Komponenten bauen konnte und meist auch ohne die Anwendung oder die DLLs zu kompilieren dann auch weiter nutzen. Man muss halt nur aufpassen, dass man keine published properties löscht Oder Methoden umbenennt.

Allerdings ist zu empfehlen, vorhandene Projekte neu zu übersetzen, wenn man ein neues Package baut
Dann könnte man gleich eine Single-Exe nehmen ohne all die Zeit mit Package-Issues zu verschwenden.
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
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 22:34 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