Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Stream an DLL übergeben (https://www.delphipraxis.net/185784-stream-dll-uebergeben.html)

sephraina 6. Jul 2015 13:16


Stream an DLL übergeben
 
Hallo Zusammen,

zuerst einmal bin ich mir nicht sicher ob das Thema im richtigen Forum platziert ist...

Mein Problem ist folgendes:
ein idhttp-client schickt einen Stream an den Server. Dieser zeigt ihn auch bei Aufruf des
Delphi-Quellcode:
Arequestinfo.PostStream
an.
Nur muss ich diesen aber noch in meine DLL bekommen, da von dort die Weiterverarbeitung läuft.

Meine Frage konkret: wie übergebe ich einen Stream an eine DLL?
(In dem gesendeten Stream ist ein xml-Dokument verpackt.)

Wenn der Client ein Get-Request macht hole ich so die Daten aus der DLL:
Delphi-Quellcode:
procedure TFServer.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var s: TMemorystream;
    str : TStringstream;
    df: string;
    p: integer;
    Handle: THandle;
    Anzeigen: TAnzeigen;

begin
    s:= TMemorystream.Create;
    str:= TStringStream.Create;
    p := pos('/',ARequestInfo.URI);
    df := rightstr(ARequestInfo.URI, length(ARequestInfo.URI)-p);
    try
    handle := Loadlibrary(pchar('PServerDLL.dll'));
    if handle <> 0 then
       begin
           //*******************************GET********************************
           if ARequestInfo.Command ='GET' then
              begin
                   @Anzeigen := GetProcAddress(Handle,PCHAR('DataOutputStr'));
                   if @Anzeigen <> nil then s := Anzeigen(df,xm);      //<<-- funktioniert, liefert ein Stream an den Client zurück mit Inhalt: xml-File welches angefordert wurde
              end
            //*******************************POST**********************************
             else if ARequestInfo.Command ='POST' then
                  begin
                       showmessage('Post1');
                       //str.LoadFromStream(Arequestinfo.PostStream);
                       //showmessage('pServer: '+str.DataString);

                       @Anzeigen := GetProcAddress(Handle,PCHAR('DataInputStr')); //<<-- 'DataInputStr' ist die procedure die den Stream in der DLL aufnehmen soll
                       if @Anzeigen <> nil then s := Anzeigen(df,xm);

                  end


       end;
    AResponseInfo.ContentStream := s;  //<<--- Zurück an Server
Hoffe jemand weiss zu helfen.. :|

Update:
(function in der DLL ist:
Delphi-Quellcode:
function DataInputStr(c: string; x: IXMLDocument): TMemoryStream;
Also in die DLL komme ich, nur wenn ich den Stream-Inhalt abrufe, ist er leer.
Wenn ich das x des Xml-Dokumentes abfrage ist da nur das Dummy-xml drin und nicht das welches der client gesendet hat.

Photoner 6. Jul 2015 16:26

AW: Stream an DLL übergeben
 
Ich habe es leider noch nicht verstanden was du da genau vorhast, aber mir fällt folgendes auf:

Du erzeugst den MemoryStream zweimal

Delphi-Quellcode:
s := TMemoryStream.Create;
und in der Dll vermutlich noch einmal:

Delphi-Quellcode:
function DataInputStr(c: string; x: IXMLDocument): TMemoryStream;
Entweder den Stream als Parameter übergeben und sich auch ums Freigeben kümmern oder die Dll erzeugen lassen und dann nach dem Aufruf freigeben (finde ich nicht so toll).

Sir Rufo 6. Jul 2015 18:39

AW: Stream an DLL übergeben
 
Eine Klassen-Instanz tauscht man niemals über die Anwendungsgrenzen hinaus.

Was man austauschen kann ist ein Speicherbereich und bei einem Stream würde sich ja ein Byte-Array anbieten. Das liegt einfach so im Speicher und kann dann problemlos ausgetauscht werden. Ein Delphi-Referenz durchsuchenIStream würde auch funktionieren.

hoika 7. Jul 2015 05:35

AW: Stream an DLL übergeben
 
Hallo,
da es sich um eine Xml-Datei handelt,
könntest du sie auch als String übergeben,
den StringStream hast du ja bereits.


Heiko

frankyboy1974 7. Jul 2015 08:55

AW: Stream an DLL übergeben
 
Hallo,


ein wenig OT:

Zitat:

Eine Klassen-Instanz tauscht man niemals über die Anwendungsgrenzen hinaus.
@Sir Rufo Was verstehts du unter Klassen-Instanz (=Object???) und seit wann überschreitet man Anwendungsgrenzen wenn man eine DLL dynamisch einbindet?

mfg

frank

Sir Rufo 7. Jul 2015 09:32

AW: Stream an DLL übergeben
 
Nun ich verstehe unter einer Klassen-Instanz das, was allgemein üblich als Klassen-Instanz verstanden wird:

Das ist eine Klasse:
Delphi-Quellcode:
type
  TMyClass = class
  end;
Das ist eine Instanz dieser Klasse:
Delphi-Quellcode:
var
  MyClassInstance: TMyClass;
begin
  MyClassInstance := TMyClass.Create; // Instanz erzeugen und die Referenz zu dieser Instanz in der Instanz-Referenz-Variablen ablegen
end;
Seit wann man die Anwendungsgrenzen überschreitet ... lass mich kurz überlegen ... seit schon immer?

Nachlesen kann man das zur Genüge hier im Forum, bei google, bei ...

Das Problem ist einfach, dass der Klassentyp
Delphi-Quellcode:
TMyClass
, wenn dieser der Anwendung und der DLL bekannt sind, trotzdem beide NICHT gleich sind, denn die DLL hat daraus einen eigenen Typen erstellt und die Anwendung auch. Die heißen gleich, sind aber nicht gleich.

Oder warum, denkst du, muss man sich beim Verwenden der Windows API immer mit diesen Struct und PChar herumschlagen?

frankyboy1974 7. Jul 2015 10:24

AW: Stream an DLL übergeben
 
Hallo Sir Rufo,

die Instanz einer Klasse bezeichnet man in der OO Programmierung gemeinhin als Objekt. Ich war mir eben nicht ganz sicher, ob wir an der Stelle über das gleiche Reden. Aber das ist wohl nicht das Problem.
Wenn ich eine DLL einbinde, und dort die exportiere Funktionalität benutze, ist dies eben nicht Anwendungsübergreifend. Die Anwendung wird nur um die Funktionalität erweitert, es wird eben keine neue Anwendung gestartet, die die Funktion der DLL ausführt.

Wenn ich beide Seite programmiere, kann ich auch sicherstellen, das beide Seite gleich sind. (Ob es heute noch Sinn macht Funktionalität in eine DLL zu packen und diese dann aus einem anderem Programm selbst zu nutzen, lasse ich dahingestellt)

Das man bei der Windows API solche Sachen wie PChar und Struct benutzt, liegt wahrscheinlich daran, dass Windows wohl in C/C++ geschrieben wurden ist.

Meine Frage lautet aber immer noch, gibt es einen technischen Grund, weswegen mann bei einem Funktionaufruf einer DLL als Übergabeparameter keine Objekte benutzen sollte. Für mich als technischer Laie, stellt sich ein Funktionaufruf einer DLL, genauso dar, als würde ich eine Methode in meinem eigenem Programm aufrufen. Ohne es je ausprobiert zu haben und ohne sagen zu wollen ob Sinnvoll oder nicht, technisch müsste es eigentlich funktionieren.

mfg

frank

Union 7. Jul 2015 10:46

AW: Stream an DLL übergeben
 
Zitat:

Zitat von frankyboy1974 (Beitrag 1307951)
Für mich als technischer Laie, stellt sich ein Funktionaufruf einer DLL, genauso dar, als würde ich eine Methode in meinem eigenem Programm aufrufen. Ohne es je ausprobiert zu haben und ohne sagen zu wollen ob Sinnvoll oder nicht, technisch müsste es eigentlich funktionieren.

Und genau das ist das Problem. Wenn Du so etwas machen möchtest, solltest Du die harte Arbeit den Spezialisten überlassen und z.b. Hydra einsetzen. Im Source kann das selbe stehen, in den zwei Instanzen (exe+dll) sind das trotzdem technisch nicht die selben Klassen.

mkinzler 7. Jul 2015 10:49

AW: Stream an DLL übergeben
 
Zitat:

Meine Frage lautet aber immer noch, gibt es einen technischen Grund, weswegen mann bei einem Funktionaufruf einer DLL als Übergabeparameter keine Objekte benutzen sollte. Für mich als technischer Laie, stellt sich ein Funktionaufruf einer DLL, genauso dar, als würde ich eine Methode in meinem eigenem Programm aufrufen.
Das ist aber nicht das selbe. Bei der Übergabe in eine Prozedur im selben Programm werden diese von gleichen Speichermanager verwaltet. Bei der Übergabe in eine Funktion, welche aus der einer Dll importiert wurde von vercshiedenen Speichermamangern ( auch wenn diese auch in Delphi geschrieben wurde.)
Zitat:

Ohne es je ausprobiert zu haben
Dann würdest Du sehen, dass es möglicherweise kracht
Zitat:

und ohne sagen zu wollen ob Sinnvoll oder nicht, technisch müsste es eigentlich funktionieren.

frankyboy1974 7. Jul 2015 11:21

AW: Stream an DLL übergeben
 
Hallo,

Zitat:

Und genau das ist das Problem. Wenn Du so etwas machen möchtest, solltest Du die harte Arbeit den Spezialisten überlassen und z.b. Hydra einsetzen.
Wenn ich behauptet, dass ich ein technischer Laie sei, war dies ironisch gemeint. Ich hab neben einem Informatikstudium circa 10 Jahre als Delphi-Entwickler hinter mir.:-D

Zitat:

Das ist aber nicht das selbe. Bei der Übergabe in eine Prozedur im selben Programm werden diese von gleichen Speichermanager verwaltet. Bei der Übergabe in eine Funktion, welche aus der einer Dll importiert wurde von vercshiedenen Speichermamangern ( auch wenn diese auch in Delphi geschrieben wurde.)
Dem Einwand kann ich so erstmal nicht widersprechen, werde ich morgen mal ausprobieren. Meine Frage an Sir Rufo war ursprünglich auch so gemeint, dass ich eigentlich keinen Grund sehen, warum es technisch nicht möglich sein sollte, ein Objekt direkt zu übergeben (ob sinnvoll oder nicht). Ich dachte immer, dass wenn ich eine Funktion aufrufe, die Übergabeparameter auf den Stack gepackt werden (bzw. in die Register geschoben), und dann der PC umgebogen wird, und ab da läuft alles wie gehabt (Befehl einlesen, Befehl ausführen, gucken wo steht nächster Befehl). Scheint doch komplizierter als gedacht.:roll::oops:

mfg

frank


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:58 Uhr.
Seite 1 von 2  1 2      

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