Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Stream aus DLL empfangen? (https://www.delphipraxis.net/203916-stream-aus-dll-empfangen.html)

skoschke 7. Apr 2020 07:52

Stream aus DLL empfangen?
 
Hallo,

wie ich einen Stream an eine DLL übergeben kann, ist bekannt.
Nun aber benötige ich den umgekehrten Weg, eine DLL soll einen Stream befüllen den ich im Hauptprogramm weiterverwenden möchte.
Klar könnte ich den Inhalt temporär in eine Datei speichern, aber ohne Zwischenspeicherung wäre mir lieber.

Hat jemand ein paar Zeilen Beispielcode?

Ciao
Stefan

TiGü 7. Apr 2020 08:35

AW: Stream aus DLL empfangen?
 
Delphi-Quellcode:
program IStreamTest;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils,
  System.Classes,
  Winapi.Windows,
  Winapi.ActiveX;

// In der DLL
function DLLFunctionToFillStream(const AStreamForDLL: IStream): Boolean stdcall;
var
  SampleBuffer: TBytes;
  BytesWritten: FixedUInt;
  HR: HRESULT;
begin
  SampleBuffer := [$D, $E, $A, $D, $B, $E, $E, $F];
  HR := AStreamForDLL.Write(SampleBuffer, Length(SampleBuffer), @BytesWritten);
  Result := Succeeded(HR) and (BytesWritten > 0);
  if not Result then
  begin
    // Fehlercode von HR loggen, Festplatte formattieren, Selbstzerstörung starten....das übliche!
  end;
end;

// Dein Programm
procedure Main;
var
  YourStream: TBytesStream;
  StreamForDLL: IStream;
  DebugStr: string;
  I: Integer;
begin
  YourStream := TBytesStream.Create;
  StreamForDLL := TStreamAdapter.Create(YourStream, TStreamOwnership.soOwned);
  if DLLFunctionToFillStream(StreamForDLL) then
  begin
    Writeln('Success!');
    DebugStr := '';
    for I := 0 to YourStream.Size - 1 do
      DebugStr := DebugStr + YourStream.Bytes[I].ToHexString(1);

    Writeln(DebugStr);
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.

himitsu 7. Apr 2020 11:13

AW: Stream aus DLL empfangen?
 
Nja, man kann auch die Daten ganz "klassich" als
Delphi-Quellcode:
(Buffer: Pointer; Length: Integer)
übergeben,

Jupp, es gibt im Windows das MSDN-Library durchsuchenIStream-Interface, inkl. MSDN-Library durchsuchenISequentialStream, und Interfaces kannst du problemlos zwischen Modulen umherreichen.
TStream und dessen Nachfahren implementieren das aber nicht,
allerdings kann man es den in einem fertigen Adapter-Interface verpacken.

Delphi-Quellcode:
var
  InnerStream: TStream;
  Stream: IStream;
 
InnerStream := TFileStream oder sonstwas;
Stream := TStreamAdapter.Create(InnerStream, soOwned); // ab hier sollte die Objektreferenz besser nicht mehr verwendet werden (und natürlich auch kein .Free)

// oder z.B. direkt (so kommt man garnicht erst auf blöde Ideen)
Stream := TStreamAdapter.Create(TFileStream.Create(Path, fmOpenRead), soOwned);
und Stream kann nun beliebig als VAR- oder OUT-Parameter oder als RESULT übergeben werden.



Selbst ShareMem würde für TStream nicht ausreichen,
wenn dann ginge es nur indem man mit Packages kompiliert (mindestens RTL), da man hierfür auf beiden Seiten nicht nur einen gemeinsamen Speichermanager, sondern vor allem die selbe RTTI benötigt.

skoschke 7. Apr 2020 13:56

AW: Stream aus DLL empfangen?
 
Prima, vielen herzlichen Dank!

Ciao
Stefan

DP-Maintenance 7. Apr 2020 15:03

Dieses Thema wurde am "07. Apr 2020, 16:03 Uhr" von "Luckie" aus dem Forum "Algorithmen, Datenstrukturen und Klassendesign" in das Forum "Programmieren allgemein" verschoben.


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