Because the function signature format of serviceobject is uniform, only one aparams: olevariant can be passed as the parameter. Multiple parameters of the client must be transmitted using arrays. For example:
VaR <br/> vparams: olevariant; <br/> vresult: integer; <br/> begin <br/>... <br/> vparams: = vararraycreate ([0, 1], varvariant); <br/> vparams [0]: = 3; <br/> vparams [1]: = 2; <br/>... <br/> vresult: = bizservice. call ('System. test', 'sum', vparams );
However, this method is not intuitive. The elements in aparams are heavily dependent on the order. Once written, it is difficult to change. Another method is to use serialized objects, such:
Tmarshalsumparams = Class <br/> published <br/> A: integer; <br/> B: integer <br/> end;
This component is serialized into a stream using a certain encoding method, so that it is easy to pass to the server. The server's serviceobject then deserializes stream tw.alsumparams.
Serialization in Delphi can be used in two ways:
1. Use twriter and treader. These two components are used by Delphi to read and write their DFM files. They are also working when you cut/paste the components. However, the two components only write the published attribute of the component and are not specially considered for serialization on the client server. Therefore, none of the data types not supported by published are processed, such as dynamic arrays, variant only supports byte arrays. Here you need to modify. Twriter writes binary streams, which are more efficient than text streams.
Procedure tvariantwriter. writearray (const value: variant); <br/> var <br/> I: integer; <br/> Lo, hi: integer; <br/> begin <br/> writevalue (vaarray); <br/> lo: = vararraylowbound (value, 1); <br/> Hi: = vararrayhighbound (value, 1); <br/> write (Lo, sizeof (integer); <br/> write (HI, sizeof (integer); <br/> for I: = Lo to Hi Do writevariant (value [I]); <br/> end; </P> <p> procedure tvariantwriter. writevariant (const value: variant); <br/> var <br/> customtype: tcustomvarianttype; <br/> outerstream, innerstream: tmemorystream; <br/> outerwriter: twriter; <br/> streamsize: integer; <br/> varstreamer: ivarstreamable; <br/> lint64: int64; <br/> begin <br/> If varisarray (value) then <br/> begin <br/> If (vartype (value) and varbyte) = varbyte then <br/> writebytearray (value) <br/> else <br/> writearray (value); <br/> end <br/> else <br/> case vartype (value) and vartypemask of <br/> varempty: <br/> writevalue (vanil); <br/> varnull: <br/> writevalue (vanull); <br/> varolestr: <br/> writewidestring (value); <br/> varstring: <br/> writestring (value); <br/> varbyte, var1_int, varword, varsmallint, varinteger: <br/> writeinteger (value); <br/> varsingle: <br/> writesingle (value); <br/> vardouble: <br/> writefloat (value ); <br/> varcurrency: <br/> writecurrency (value); <br/> vardate: <br/> writedate (value); <br/> varboolean: <br/> If value then <br/> writevalue (vatrue) <br/> else <br/> writevalue (vafalse); <br/> varlongword, varint64: <br/> begin <br/> lint64: = value; <br/> writeinteger (lint64); <br/> end; <br/> else <br/> try <br/> if not findcustomvarianttype (tvardata (value ). vtype, customtype) or <br/> not supports (value, ivarstreamable, varstreamer) Then <br/> writestring (value) <br/> else <br/> begin <br/> innerstream: = nil; <br/> outerstream: = tmemorystream. create; <br/> try <br/> innerstream: = tmemorystream. create; <br/> outerwriter: = twriter. create (outerstream, 1024); <br/> try <br/> varstreamer. streamout (tvardata (value), innerstream); <br/> streamsize: = innerstream. size; </P> <p> outerwriter. writestring (customtype. classname); <br/> outerwriter. write (streamsize, sizeof (streamsize); <br/> outerwriter. write (innerstream. memory ^, streamsize); <br/> finally <br/> outerwriter. free; <br/> end; <br/> streamsize: = outerstream. size; <br/> writevalue (vabinary); <br/> write (streamsize, sizeof (streamsize); <br/> write (outerstream. memory ^, streamsize); <br/> finally <br/> innerstream. free; <br/> outerstream. free; <br/> end; <br/> Reset T <br/> raise ewriteerror. createres (@ swriteerror); <br/> end;
2. Use soap to encode the tremotable component in XML format. Similarly, it only supports byte Arrays for variant. If you want to support other Variant Types, You need to transform them yourself. It should be noted that the XML encoding efficiency is relatively low, and the larger the data volume, the more obvious.
Function tmarshalcomponent. _ externaltoxmlstream (<br/> astream: tstream): widestring; <br/> const <br/> Signature: widechar = # $ feff; <br/> var <br/> vdoc: ixmldocument; <br/> vconverter: iobjconverter; <br/>{$ ifdef ver150} <br/> refID: widestring; <br/>{$ else} <br/> refID: invstring; <br/>{$ endif} <br/> begin <br/> // Why is no encoding output in the XML file? <Br/> ActiveX. coinitialize (NiL); <br/> vdoc: = txmldocument. create (NiL); <br/> try <br/> (vdoc as ixmldocumentaccess ). required entobject. domvendor: = getdomvendor (smsxml); <br/> vdoc. active: = true; </P> <p> vdoc. version: = '1. 0'; <br/> vdoc. standalone: = 'yes'; <br/> vdoc. encoding: = 'utf-8'; </P> <p> vdoc. documentelement: = vdoc. createnode (self. classname); <br/> vconverter: = optosoapdomconv. toptosoapdomconvert. create (NiL); <br/> try <br/> vconverter. objinstancetosoap (self, vdoc. documentelement, vdoc. documentelement, <br/> self. classname, '', [], refID); <br/> // The savetostream encoding is incorrect. <br/> vdoc. savetoxml (result); <br/> // Add a signature; otherwise, ie cannot open <br/> result: = signature + result; <br/> If astream <> nil then <br/> begin <br/> astream. size: = 0; <br/> astream. write (result [1], length (result) * 2); <br/> end; <br/> vdoc. active: = false; <br/> finally <br/> vconverter: = nil; <br/> end; <br/> finally <br/> vdoc: = nil; <br/> ActiveX. couninitialize; <br/> end;
In delphi2010, JSON format serialization is supported. It should be more efficient than XML.
Once serialized to stream, we can use any compression method to compress before transmission, such as zlib, Leo, and so on.