Einzelnen Beitrag anzeigen

s-off

Registriert seit: 20. Jan 2010
89 Beiträge
 
Delphi 2010 Professional
 
#1

Weitergabe eines Strings über Pointer funktioniert nicht - manchmal...

  Alt 28. Mai 2021, 14:44
Delphi-Version: 10.1 Berlin
Hallo zusammen,

ich habe mich lange Zeit nicht mehr mit Delphi beschäftigt und stehe nun vor einem Problem, welches ich alleine anscheinend nicht bewältigen kann.
Folgende Ausgangs-Situation:
Ich muss aus C# eine Delphi-DLL mit Parametern (BSTR -> WideString) aufrufen, in der DLL ein PDF erzeugen und dieses base64-decodiert wieder zurückgeben.
Das funktioniert auch alles; naja - der Aufruf zumindest und es kommt auch etwas zurück.

Das Problem, mit welchem ich derzeit kämpfe ist folgendes:
Die Delphi-DLL ist sehr komplex und es erfolgt eine lange Kette von Prozedur-/Funktionsaufrufen.
Am Ende der Kette wird der String erzeugt, welchen ich am Anfang der DLL wieder herausgeben muss. Die PDF-Engine schreibt dazu in einen StringStream.
Da es sehr aufwändig wäre, diesen String - nachträglich - durch die Prozeduren/Funktionen durchzureichen (würde einen sehr großen Aufwand bedeuten), dachte ich mir, dass ich das über Pointer realisiere.
Das Resultat: mal geht es, mal nicht und ich glaube, dass das am Speicherreservieren usw. hängt.

In der DLL habe ich ein paar Variablen in die ich später die Adresse für die PDF-Daten sowie deren Größe schreibe und entsprechende Pointer darauf.
Delphi-Quellcode:
   // in der DLL
   BinaryContentAddress: Integer; // address of the binary content
   PBinaryContentAddress: ^Integer;
   BinaryContentSize: Integer; // size of the binary content
   PBinaryContentSize: ^Integer;
Diese übergebe ich in die Klasse, die das PDF-Dokument erzeugt.
Delphi-Quellcode:
   // Aufruf der Methode Data2Ext der Klasse 1
   Data2Ext(PBinaryContentAddress, PBinaryContentSize, PStringContentAddress, PStringContentSize);

   // ...
   
   // Implementierung in Klasse 1
   FOutputStreamInt: TStringStream; // internal stream for the binary content
   FAddressBinaryContent: Integer; // binary content address
   FAddressBinaryContentSize: Integer; // binary content size address

   // ...

   // Methode Data2Ext in Klasse 1
   FOutputStreamInt := TStringStream.Create;
   FAddressBinaryContent := BinaryContentAddressPointer;
   FAddressBinaryContentSize := BinaryContentSizePointer;

   // ...

   // Methode, die die Pointer für die Rückgabe aufbereitet
   Var
      PBinaryContent: ^Integer; // pointer to the binary content address
      PBinaryContentSize: ^Integer; // pointer to the binary content size
      BinaryContent: PChar;
   Begin

      If (FAddressBinaryContent > 0) And (FAddressBinaryContentSize > 0) Then Begin

         // get external addresses
         PBinaryContent := Pointer(FAddressBinaryContent);
         PBinaryContentSize := Pointer(FAddressBinaryContentSize);

         // write the pchar address to the external address
         BinaryContent := CoTaskMemAlloc((Length(FOutputStreamInt.DataString) + 1));
         Move(FOutputStreamInt.DataString[1], BinaryContent^, Length(FOutputStreamInt.DataString) + 1);
         PBinaryContent^ := Cardinal(BinaryContent);

         // write the binary content size to the external address
         PBinaryContentSize^ := Length(FOutputStreamInt.DataString);

         If Assigned(FOutputStreamInt) Then
            FreeAndNil(FOutputStreamInt);
      End;
Wenn das Ganze durch ist bin ich wieder zurück am Anfang der DLL.
Dort möchte ich die PDF-Daten auslesen, in einen String schreiben, base64 codieren und an den Aufrufer zurückgeben.
Delphi-Quellcode:
Var
   pBinaryContent: PChar;
Begin
   // Get the pdf data address and its size
   If PBinaryContentAddress <> Nil Then
      BinaryContentAddress := PBinaryContentAddress^;
   If PBinaryContentSize <> Nil Then
      BinaryContentSize := PBinaryContentSize^;

   // Get the content
   SetLength(sBinaryContent, BinaryContentSize);
   Move(PChar(BinaryContentAddress)^, sBinaryContent[1], BinaryContentSize);

   sBase64Content := Coder.EncodeBase64(sBinaryContent);

   // ...
So weit, so gut.
Wie bereits gesagt - manchmal ist der String invalide, der da rauskommt und manchmal nicht.
Und ich fürchte, dass ich da irgendetwas grundlegend falsch mache.
Ich hoffe, dass mir hier jemand behilflich seine kann.

Besten Dank im Voraus.
Gruß
s-off
  Mit Zitat antworten Zitat