#1 2021-01-10 16:47:19

JD
Member
Registered: 2015-08-20
Posts: 101

[Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Hi there everyone,

I want to create a simple JSON object with a list of IDs like this: {id: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}. I want to later loop over the array and save the IDs to a database.

This is the code I want to use to create the array is this:

// Create a JSON object like this:
// {id: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
//
procedure TForm1.Button1Click(Sender: TObject);
var
  vJSON: Variant;
  intX: integer;
begin
  //
  TDocVariant.New(vJSON);
  vJSON := _Json('{id:[]}');
  //
  for intX := 1 to 10 do
    vJSON.id.Add(intX);
end;

However, the code fails on

vJSON.id.Add(intX);

with the message No variant method call dispatch.

What am I doing wrong?

Thanks a lot,

JD

Last edited by JD (2021-01-11 00:43:37)

Offline

#2 2021-01-10 17:54:36

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

I guess the error comes from

vJSON := _Json('{id:[]}');

Try

vJSON := _Json('{"id":[]}');

Also I think there is no need in

TDocVariant.New(vJSON);

Offline

#3 2021-01-10 21:35:52

JD
Member
Registered: 2015-08-20
Posts: 101

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Vitaly wrote:

I guess the error comes from

vJSON := _Json('{id:[]}');

Try

vJSON := _Json('{"id":[]}');

Also I think there is no need in

TDocVariant.New(vJSON);

Thanks for your reply but it still does not work. I still get the same error.

By the way, I used the same method at the example in https://synopse.info/files/html/Synopse … l#TITLE_39

There we have

var V: variant;
 ...
  V := _Json('{arr:[1,2]}');
  V.arr.Add(3);     // will work, since V.arr is returned by reference (varByRef)
  writeln(V);       // will write '{"arr":[1,2,3]}'

So even this example from the documentation does not work anymore.

JD

Last edited by JD (2021-01-10 21:51:50)

Offline

#4 2021-01-10 21:51:09

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

JD wrote:

Thanks for your reply but it still does not work. I still get the same error.

Yeah, sorry, you're right. I took a look at _Json function. Quotes are not necessary:

// - in addition to the JSON RFC specification strict mode, this method will
// handle some BSON-like extensions, e.g. unquoted field names:

I made a test. In my case (D10.4.1) your code works without any error in both cases.

upd: tested it with 10.3.3 and 10.2.3 also - all goes fine

Last edited by Vitaly (2021-01-10 21:56:17)

Offline

#5 2021-01-10 22:02:21

JD
Member
Registered: 2015-08-20
Posts: 101

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

That's very strange. I'm using Lazarus 2.1.0/FPC 3.2 (built with fpcupdeluxe) on Windows 10. It used to work perfectly but I only just noticed it failed 2 daya ago when I could no longer save new records to my database.

JD

Offline

#6 2021-01-10 22:36:11

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Well, if it is FPC-only related problem, then maybe it is a case of https://synopse.info/files/html/Synopse … l#TITLE_40
Unfortunately, my installed FPC (CodeTyphon) is pretty much outdated (haven't used it for years) and it doesn't work as it is with my current mORMot sad

Offline

#7 2021-01-10 23:08:46

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

As described in the documentation, it is not recommended to use late binding in Lazarus / FPC.

Use TDocVariantData.
You can cast the Variant with TDocVariantData(V).Add ..., or use a TDocVariantData directly.

var
  D : TDocVariantData;
  V : Variant;
...
  D.Init();
  D.A_['id'].AddItem(1);
  D.A['id'].AddItem(2); 
  writeln(D.ToJSON());       //'{"id":[1,2]}'


  //using with
  D.Init();
  with D.A_['id']^ do
  begin
    AddItem(1);
    AddItem(2);
  end;     
  writeln(D.ToJSON());       //'{"id":[1,2]}'


  //Casting the variant
  V := _Json('{id:[]}');
  TDocVariantData(V).A['id'].AddItem(1);
  TDocVariantData(V).A['id'].AddItem(2);
  writeln(VariantSaveJSON(V)); //'{"id":[1,2]}'

Last edited by macfly (2021-01-10 23:23:14)

Offline

#8 2021-01-10 23:27:17

JD
Member
Registered: 2015-08-20
Posts: 101

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Thanks a lot for your contributions. I found that this worked for me also:

procedure TForm1.Button3Click(Sender: TObject);
var
  vJSON: Variant;
  intX: integer;
begin
  vJSON := _Json('{"id":[]}');
  //
  for intX := 1 to 10 do
    _Safe(vJSON.id)^.AddItem(intX);
  ShowMessage(VariantToUTF8(vJSON));
end;

JD

Offline

#9 2021-01-10 23:43:01

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

I guess this code might be slightly better since it will get the pointer just one time:

  with _Safe(vJSON.id)^ do
    for intX := 1 to 10 do
      AddItem(intX);

or local variable can be also an option.
Anyway, these are just details, of course.

Offline

#10 2021-01-11 00:43:06

JD
Member
Registered: 2015-08-20
Posts: 101

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Vitaly wrote:

I guess this code might be slightly better since it will get the pointer just one time:

  with _Safe(vJSON.id)^ do
    for intX := 1 to 10 do
      AddItem(intX);

or local variable can be also an option.
Anyway, these are just details, of course.

Yes that works also. Thanks a lot.

JD

Offline

#11 2021-01-28 20:27:41

PascalDragon
Member
From: Germany
Registered: 2016-06-01
Posts: 12

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

macfly wrote:

As described in the documentation, it is not recommended to use late binding in Lazarus / FPC.

Do you have a self contained example that shows custom variants failing (preferrably not depending on mORMot)? I can't reproduce it with a simple example using TInvokableVariantType. If I have a simple example to reproduce it, I can fix it.


Free Pascal Compiler Core developer

Offline

#12 2021-01-28 20:47:47

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

PascalDragon wrote:
macfly wrote:

As described in the documentation, it is not recommended to use late binding in Lazarus / FPC.

Do you have a self contained example that shows custom variants failing (preferrably not depending on mORMot)? I can't reproduce it with a simple example using TInvokableVariantType. If I have a simple example to reproduce it, I can fix it.



I'm not sure if we're talking about the same thing.

But here's an example where calling a function via late binding will fail in FPC.

var
  ADoc: Variant;  
...
  TDocVariant.New(ADoc); //or ADoc := _Json('[]');    

  ADoc.Add('Some Text'); //<- here

Last edited by macfly (2021-01-30 12:33:15)

Offline

#13 2021-01-31 21:30:08

PascalDragon
Member
From: Germany
Registered: 2016-06-01
Posts: 12

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

It seems that so far FPC behaves correctly here nowadays. I've tested the TDocVariant code with the ifdefs for FPC removed from TDocVariant.DoFunction from mORMot2 with trunk, 3.2.0 and (after disabling the RTTI code in mORMot2) 3.0.4 and all work without error. I've additionally added a test to FPC's testsuite that ensures that TVarData passed as const is passed as reference so that this behavior will be consistent across platforms (which it is already, but this prevents this from breaking).

So in my opinion this can be enabled in mORMot for FPC. If there should still be problems, then report them to our bug tracker with a self contained example, please.


Free Pascal Compiler Core developer

Offline

#14 2021-02-12 07:14:43

Leslie7
Member
Registered: 2015-06-25
Posts: 248

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

PascalDragon,

I just want to say that it is great to have you here. Your attention to make mORMot and FPC work well together is appreciated. smile

Offline

#15 2022-09-16 14:22:46

udihamudi
Member
Registered: 2022-09-16
Posts: 14

Re: [Solved] No variant method call dispatch error (occurs in Lazarus/FPC)

Hello sorry I know its old thread - and I am completely new to Lazarus etc. so I am not even sure this thread is observed, anyhow I seem to have similar issue, the project compiles and starts fine, when I try to use it I get the an error "No variant method call dispatch." Is it the same issue as above? Also, how can I debug it and see what source file and line the error comes from?

Thanks a lot!!

Offline

Board footer

Powered by FluxBB