Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi 7 : Converting (serializing?) an object to TByteDynArray (for SOAP)

Tags:

delphi

I use Delphi 7 and import from a WDL file to create a SOAP client. Delphi generates interface code with the published functions from the WSDL and the types (classes) of parameters for those functions.

Delphi has determined that something like this

  Message = class(TRemotable)
  private
    FMessageID: Int64;
    Ftimestamp: TXSDateTime;
    Fevent: eventType;
    FmagicNumber: WideString;
    FDataPart: DataPart;
  published
    property MessageID: Int64 read FMessageID write FMessageID;
    property timestamp: TXSDateTime read Ftimestamp write Ftimestamp;
    property event: eventType read Fevent write Fevent;
    property magicNumber: WideString read FmagicNumber write FmagicNumber;
    property DataPart: DataPart read FDataPart write FDataPart;
  end;

should be send as a TByteDynArray ...

function  sendMessage(const theMessage: TByteDynArray; 
                      const data: DataPart): WideString; stdcall;

which necessitates me converting an object to a TByteDnyArray, which - beings Delphi n00b - I am doing this by

  theMessageArray := TByteDynArray(theMessage);

When I look at the object in the debugger, then it contains pointers (to the Ftimestamp and Ftimestamp), and when I look in the TByteDynArray I see the self same pointer values. So, it seems that "cast" is not what I wanted. How do convert my object to the TByteDynArray which is required? (and which, presumably "inlines" the objects pointed to by pointers)

I presume that there is a standard approach for this ...

like image 955
Mawg says reinstate Monica Avatar asked Mar 12 '26 15:03

Mawg says reinstate Monica


1 Answers

Look in the parent class for a way to stream the data. objectinstance.savetostream or so. It probably will iterate over the published membes and write them to a stream.

Use this to write it to a memory stream, which is roughly a class around a memory block (like tdynbytearray). Then use memorystream.size and setlength to allocate the tbytedynarray to the proper size, and copy the bytes from the memorystream to the newly created array:

 // (Untested)

 memstream:=TMemoryStream.Create;
 objectinstance.SaveToStream(memstream);
 setlength(mybytearray,memstream.size);
 if memstream.size>0 then
    move (pansichar(memstream.memory)^,mybytearray[0],memstream.size);
like image 175
Marco van de Voort Avatar answered Mar 15 '26 10:03

Marco van de Voort



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!