#1 2022-05-05 08:23:26

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

TDocVariant.names raise AV

Hello,
I try to replace superobject with TDocVariant (Delphi 7).
I have a problem (access violation) when I try to access Names property eg DocVariantData(mydoc).Names.
If on TDocVariantData add a new property NamesEx and use a function to return VName private variable then it works.

Is I missing something?

Offline

#2 2022-05-05 09:59:10

igors233
Member
Registered: 2012-09-10
Posts: 233

Re: TDocVariant.names raise AV

Probably, consider using TDocVariantData, load json and then from debugger check what values/properties are there.

Offline

#3 2022-05-05 11:22:37

tbo
Member
Registered: 2015-04-20
Posts: 335

Re: TDocVariant.names raise AV

dka1 wrote:

I have a problem (access violation) when I try to access Names property eg DocVariantData(mydoc).Names.

I'm not sure I understood you correctly, but is this what you mean:

var
  item: Variant;
begin
  TDocVariant.New(item);
  item.Names := 'test';
  WriteLn(item.Names);
  WriteLn(TDocVariantData(item).S['Names']);

With best regards
Thomas

Offline

#4 2022-05-05 15:00:20

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

I mean DocVariantData(item).Names[0]

Offline

#5 2022-05-05 15:02:54

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

actually DocVariantData(item)^.Names[0]

Offline

#6 2022-05-05 21:23:13

igors233
Member
Registered: 2012-09-10
Posts: 233

Re: TDocVariant.names raise AV

As far as I could see that should work, but I guess your actual code is more complicated, perhaps you're trying to use variant that's not json object.
When converting variant to TDocVariantData or PDocVariantData, use _Safe for conversion.

Offline

#7 2022-05-06 07:38:39

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

Thanks for your answerers but my problem exists.
Here a simple code that raise AV
var v: variant;
begin
  TDocVariant.New(v);
  v.Code:= '000';
  v.Descr:= 'xxx';
  DocVariantData(v).Names[0]:= '222';

Offline

#8 2022-05-06 07:42:48

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

also it work v.name(0) eg showmessage(v.name(0))
but is read only

Offline

#9 2022-05-06 08:04:19

igors233
Member
Registered: 2012-09-10
Posts: 233

Re: TDocVariant.names raise AV

>  DocVariantData(v).Names[0]:= '222';

This works for me, both in mormot2 and mormot1.18. Delphi XE7.

If you're using latest version, perhaps D7 wasn't tested with it, try some older one (from few months or so).

Offline

#10 2022-05-06 08:08:39

pvn0
Member
From: Slovenia
Registered: 2018-02-12
Posts: 209

Re: TDocVariant.names raise AV

can you try without variant late binding?

var v : variant;
begin
  TDocVariant.New(v);
  with TDocVariantData(v) do
  begin
     U['Code'] := '000';
     U['Descr'] := 'xxx';
     Names[0] := '222';
  end;
end;

Offline

#11 2022-05-06 08:47:07

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

Ok there are very strange behavior.
1) start delphi 7 IDE that create a new project
2) write this code in TForm1.FormCreate
var v: variant;
begin
  TDocVariant.New(v);
  v.Code:= '000';
  v.Descr:= 'xxx';
  DocVariantData(v).Names[0]:= '222';
3) delete any previous project1.exe
4) compile it and run get AV
5) build and run NOW IS OK
close the IDE, then redo all  starting from step 1 and get the same behavior

Offline

#12 2022-05-06 09:27:41

sakura
Member
From: Germany
Registered: 2018-02-21
Posts: 218
Website

Re: TDocVariant.names raise AV

This is rather a behavior designed as-is in Delphi. If the DCU timestamp is newer than the timestamp of the PAS file with the same name, the DCU is considered to be correct on compile. Only a rebuild will fix that. This saves compile-time and is sufficing in most cases. This is not a fault of mORMot.

Offline

#13 2022-05-06 09:39:15

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

I did not change syncommons.pas to mark it as rebuild.
With build force IDE to recompile my unit1.pas and also syncommons.pas, SynLZ.pas (this is strange)

Offline

#14 2022-05-06 10:39:30

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

Synopsis,
bellow code run (on IDE) only if do BUILD not compile

procedure Strange;
var v: variant;
begin
  TDocVariant.New(v);
  v.Code:= '000';
  v.Descr:= 'xxx';
  showmessage(DocVariantData(v)^.NamesEx[0]); //always run <this is my property (that use a function to result:= VName)>
  showmessage(DocVariantData(v)^.Names[0])      //cause AV. Run only after BUILD
end;

Offline

#15 2022-05-06 13:06:08

igors233
Member
Registered: 2012-09-10
Posts: 233

Re: TDocVariant.names raise AV

What is NamesEx? You're doing something behind the scene which is causing these issues.
Use TDocVariantData as is, you do not have to change anything and it can cover any property or any value.

Offline

#16 2022-05-06 15:11:26

dka1
Member
From: Greece
Registered: 2017-07-25
Posts: 28

Re: TDocVariant.names raise AV

As I wrote at the beginning NamesEx Is my workaround to stop AV

dka1 wrote:

Hello,
I try to replace superobject with TDocVariant (Delphi 7).
I have a problem (access violation) when I try to access Names property eg DocVariantData(mydoc).Names.
If on TDocVariantData add a new property NamesEx and use a function to return VName private variable then it works.

Is I missing something?

Offline

#17 2022-05-06 16:10:28

igors233
Member
Registered: 2012-09-10
Posts: 233

Re: TDocVariant.names raise AV

Your example cannot compile, so either you've changed TDocVariantData and added NamesEx or sent wrong code.
I suspect you're doing something wrong, there are a lot of examples within SynCommons how to properly use json objects (through TDocVariantData or with late binding and TDocVariant) so my advice is to start from there.

Offline

Board footer

Powered by FluxBB