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.