#1 2018-01-17 16:47:03

anmendes
Member
Registered: 2018-01-17
Posts: 2

Out parameters in Interface based services

Hello,

I am using Mormot with Interface based services.

In my interface implementation, have the lines bellow:

procedure CarregaPedidoDisk(Filtro : string; out Pedido : TPedidoDisk);
procedure CarregaImpressoesPedido(PedidoGeral : integer; out Lista : TListaImpressaoPedido);

TPedidoDisk is a TPersistent class descendant and Lista is a TStringList class descendant.

The "Pedido" and "Lista" parameter have the "out" modifier. This modifier tells delphi/freepascal that the parameter is only for output.

But in implementation of "CarregaPedidoDisk" the "Pedido" parameter is initialized (automatic object create) and Lista is not initialized (The correct, in my opinion, the "out" modifier was used).


Searching in the Mormot code ("mormot.pas", TServiceMethodExecute.BeforeExecute procedure) this code is used for automatic creation:

case ValueType of
      smvObject:
        fObjects[IndexVar] := ArgTypeInfo^.ClassCreate
      smvRecord:
        if fAlreadyExecuted then
          FillcharFast(fRecords[IndexVar],ArgTypeInfo^.RecordType^.Size,0);



I suggest change the code for :


case ValueType of
      smvObject:
        if ValueDirection <> smdOut then
           fObjects[IndexVar] := ArgTypeInfo^.ClassCreate
        else
           fObjects[IndexVar] := nil;
      smvRecord:
        if fAlreadyExecuted then
          FillcharFast(fRecords[IndexVar],ArgTypeInfo^.RecordType^.Size,0);


Antonio Mendes

Offline

#2 2018-01-17 18:15:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,225
Website

Re: Out parameters in Interface based services

I understand it may be confusing.
But to be fair, I guess that almost noone is using "var" or "out" for class parameters, which are already passed by value.

So no, there is no bug, this is as expected, and as documented.
See https://synopse.info/files/html/Synopse … #TITLE_399

Behind the scene, "out" is the same as "var", at asm/call level.
As documented, here "out" is not about the instance initialization, but about the REST service serialization of the output values.
REST is about making REpresentation of the value, so a dedicated class instance does make sense.

All items are initialized, so the implementation code don't need to initialize it.
When implementing services, it is a nice feature to have, and it also make clear that you need to fill an existing class instance, which will be freed by the caller, not send away a pre-existing instance - with potential access violation if it is still used somewhere else.

See also https://synopse.info/forum/viewtopic.ph … 676#p25676

Offline

#3 2018-01-18 12:27:25

anmendes
Member
Registered: 2018-01-17
Posts: 2

Re: Out parameters in Interface based services

Ok, I understood this, but how to solve the problem with "out" parameters with TStringList and TObjectList classes that are not initialized in the procedure call by webservice?

Thanks!

Offline

#4 2018-01-18 13:16:46

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,225
Website

Re: Out parameters in Interface based services

TStringList is not supported since it lacks a virtual constructor - why not use TRawUTF8DynArray or TRawUTF8List instead?

TObjectList is not supported either, due to lack of RTTI information against the stored class type - even with generics.
Consider using T*ObjArray instead, which work with no problem.

Offline

Board footer

Powered by FluxBB