tags:

views:

112

answers:

1

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 ...

+2  A: 

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);
Marco van de Voort
+1 for replying, but will that "cast" it to a TByteDynArray ? I need too be sure that it will can be used as the parameter to a SOAP call.
Mawg
No, casting a class to anything but another class is not possible. This is called streaming, which is the usual way for this to be done
Marco van de Voort
Mawg
The parent class TRemotable does not seem to have any methods to save to stream. I guess that I will have to code my own
Mawg
hmm, isn't there a ready-made TCustomMemoryStream descendant that SetPointer's to the data-pointer-position of the start of a TByteDynArray? (if there isn't it's not that hard to make)
Stijn Sanders