Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Billiger Datenaustausch zwischen Anwendungen und DLL's (https://www.delphipraxis.net/165298-billiger-datenaustausch-zwischen-anwendungen-und-dlls.html)

Bummi 22. Dez 2011 12:37

Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Gibt bei folgender Implementierung Haken und Ösen, oder geht das prinzipiell in Ordnung?
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
type
 Tp=Procedure(s:TStreamAdapter);
var
 ms:TMemoryStream;
 isa:TStreamAdapter;
 s:String;
 h:THandle;
 p:Tp;
begin
   s :='Nur ein Test ohne weiteren Sinn';
   ms := TMemoryStream.Create;
   isa:=TStreamAdapter.Create(ms);
   try
   ms.Write(s[1],Length(s) * SizeOf(Char));
   h := LoadLibrary('ShowStream.dll');
   if h <> 0 then
      try
      @p := GetProcAddress(h,'ShowAStream');
      p(isa);
      finally
      FreeLibrary(h);
      end;
   finally
     isa.Free;
     ms.Free;
   end;
end;
____________________________________________________

library ShowStream;

uses
  SysUtils,
  Classes,
  Dialogs;

{$R *.res}


Procedure ShowAStream(isa:TStreamAdapter);
var
  ms:TMemoryStream;
  s:String;
begin
    ms:=TMemoryStream.Create;
    try
      ms.LoadFromStream(isa.Stream);
      SetLength(s,ms.Size);
      ms.Read(s[1],ms.Size);
      Showmessage(s);
    finally
      ms.Free;
    end;
end;
  Exports
  ShowAStream index 1;
begin
end.

Nersgatt 22. Dez 2011 12:46

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Delphi-Quellcode:
   ms := TMemoryStream.Create;
   isa:=TStreamAdapter.Create(ms);
   try
[...]
   finally
     isa.Free;
     ms.Free;
   end;
Nur in Bezug auf das Try-Finally-Konstrukt. Wenn im Constructor von TStreamAdapter etwas schief geht, wird ms nicht freigegeben. Daher würde das so machen:
Delphi-Quellcode:
   
   ms := nil;
   isa := nil;
   try
   ms := TMemoryStream.Create;
   isa:=TStreamAdapter.Create(ms);
[...]
   finally
     isa.Free;
     ms.Free;
   end;
Da .Free auf nil prüft ist so sichergestellt, dass immer beides freigegeben wird. :thumb:

Von dem Rest hab ich keine Ahnung. :stupid:

DeddyH 22. Dez 2011 13:00

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Ich hab da noch im Hinterkopf, dass eine Übergabe von Objektinstanzen (hier: TStreamadapter) problematisch ist. Allerdings bin ich gerade nicht sicher, ob das nur für VCL-Objekte galt.

Bernhard Geyer 22. Dez 2011 13:08

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Zitat:

Zitat von DeddyH (Beitrag 1142736)
Ich hab da noch im Hinterkopf, dass eine Übergabe von Objektinstanzen (hier: TStreamadapter) problematisch ist. Allerdings bin ich gerade nicht sicher, ob das nur für VCL-Objekte galt.

Es ist immer problematisch da die is und as-Operatoren nur funktionieren wenn DLL und Exe gemeinsame Runtime haben.
Auch wird es Problematisch wenn unterschiedliche Delphi-Versionen oder Compileroptionen verwendet werden (TMyType benötigt in DLL 40 Byte, aber in Exe 48-Byte). Wie soll da was klappen ...

Iwo Asnet 22. Dez 2011 13:11

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Was spricht gegen Variants oder einfache Speicherblöcke?

Bernhard Geyer 22. Dez 2011 13:13

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Zitat:

Zitat von Iwo Asnet (Beitrag 1142739)
Was spricht gegen Variants oder einfache Speicherblöcke?

Variants (nicht OleVariants) sind eine Delphi-Implementierung seit D6. D.h. u.U. auch inkompatible zwischen Versionen.
Wenn dann OleVariants.

Aber beides sind alternativen. Kommt halt immer auf die API an was man machen will.

snook 22. Dez 2011 13:44

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
wenn du schon TStreamAdapter verwendest, dann übergib doch ne interfacereferenz. TStreamAdapter implementiert IStream, damit kannst du dann in der DLL herrvorragend arbeiten

mal so aus der hüfte geschossen
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
type
 Tp=Procedure(const s: IStream);
var
 ms:TMemoryStream;
 isa:IStream;
 s:String;
 h:THandle;
 p:Tp;
begin
   s :='Nur ein Test ohne weiteren Sinn';
   ms := TMemoryStream.Create;
   isa:=TStreamAdapter.Create(ms, soOwned);
   try
   ms.Write(s[1],Length(s) * SizeOf(Char));
   h := LoadLibrary('ShowStream.dll');
   if h <> 0 then
      try
      @p := GetProcAddress(h,'ShowAStream');
      p(isa);
      finally
      FreeLibrary(h);
      end;
   finally
     isa := nil;
   end;
end;
____________________________________________________

library ShowStream;

uses
  SysUtils,
  Classes,
  Dialogs, ActiveX;

{$R *.res}


Procedure ShowAStream(const isa:IStream);
var
  s:String;
  StatStg: TStatStg;
  StatFlag: LongInt;
  lPos: Int64;
  pRead; PLongInt;
begin
    ms:=TMemoryStream.Create;
    try
      isa.stat(StatStg, StatFlag);
      setlength(s, StatStg.cbSize);
      isa.Seek(0, soFromBeginngin, lPos);
      isa.Read(PChar(s), StatStg.cbSize, pRead);
      Showmessage(s);
    finally
      ms.Free;
    end;
end;
  Exports
  ShowAStream index 1;
begin
end.

Bummi 22. Dez 2011 14:01

AW: Billiger Datenaustausch zwischen Anwendungen und DLL's
 
Danke Sebastian :thumb:

das war es was ich eigentlich tun/haben wollte ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 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