类型:
TData = record
str: string;
int: Integer;
boo: Boolean;
flt: Double;
end;
TDataArray = Array [0..5] of TData;
TObj = class
private
str: string;
int: Integer;
boo: Boolean;
flt: Double;
public
constructor Create(s: string; i: Integer; b: Boolean; f: Double);
end;
Testcode:
procedure TFrmJSONRTTI.FormShow(Sender: TObject);
var
DataArray,
NewArray : TDataArray;
Ob,NewOb : TObj;
so : ISuperObject;
ctx : TSuperRttiContext;
i : integer;
begin
Log('SERIALIZING Static data');
Log('');
Log('type');
Log(' TData = record');
Log(' str: string;');
Log(' int: Integer;');
Log(' boo: Boolean;');
Log(' flt: Double;');
Log(' end;');
Log('');
Log(' TDataArray = Array [0..5] of TData;');
Log('');
Log('var');
Log(' DataArray: TDataArray;');
for i := 0 to 5 do
begin
DataArray[i].str := 'str'+ inttostr(i);
DataArray[i].int := i;
DataArray[i].boo := (i > 3);
DataArray[i].flt := i;
end;
ctx := TSuperRttiContext.Create;
try
so := ctx.AsJson<TDataArray>(DataArray);
finally
ctx.Free;
end;
Log('');
Log(so.AsJson);
Log('');
Log('DE-SERIALIZING Static data');
Log('');
ctx := TSuperRttiContext.Create;
try
NewArray := ctx.AsType<TDataArray>(SO);
finally
ctx.Free;
end;
Log('New TDataArray:');
for i := 0 to 5 do
begin
Log(' DataArray['+IntToStr(i)+'].str: ' + DataArray[i].str);
Log(' DataArray['+IntToStr(i)+'].int: ' + IntToStr(DataArray[i].int));
Log(' DataArray['+IntToStr(i)+'].boo: ' + BoolToStr(DataArray[i].boo,true));
Log(' DataArray['+IntToStr(i)+'].flt: ' + FloatToStr(DataArray[i].flt));
end;
Log('------------------------------');
Log('');
Log('SERIALIZING Object');
Log('');
Log('TObj = class');
Log('private');
Log(' str: string;');
Log(' int: Integer;');
Log(' boo: Boolean;');
Log(' flt: Double;');
Log('public');
Log(' constructor Create(s: string; i: Integer; b: Boolean; f: Double);');
Log('end;');
Log('');
Ob := TObj.Create('test',5,true,1.2);
ctx := TSuperRttiContext.Create;
try
so := ctx.AsJson<TObj>(Ob);
finally
ctx.Free;
Ob.Free;
end;
Log('');
Log(so.AsJson);
Log('');
Log('DE-SERIALIZING Object');
Log('');
NewOb := TObj.Create('',0,false,0);
try
NewOb := ctx.AsType<TObj>(SO); // <== Exception $C0000005, AV at 0x0000000 read of addr 0x0000000
finally
ctx.Free;
end;
Log('New TObj:');
with NewOb do
begin
Log(' str: ' + str);
Log(' int: ' + IntToStr(int));
Log(' boo: ' + BoolToStr(boo,true));
Log(' flt: ' + FloatToStr(flt));
end;
NewOb.Free;
end;
第一部分(数组)记录工作得非常好,第二部分与TObj,我想将JSON对象解析成一个新对象在指定的位置失败。我做错了什么?
顺便说一下,我不确定是否必须在ctx.AsType之前执行 NewOb:= TObj.Create ,但在这种情况下没有区别。
答案 0 :(得分:6)
AV很清楚 - 您正在取消引用空指针。在释放之后,您将使用ctx
。
ctx := TSuperRttiContext.Create; // CREATE ctx
try
so := ctx.AsJson<TObj>(Ob);
finally
ctx.Free; // FREE ctx
Ob.Free;
end;
Log('');
Log(so.AsJson);
Log('');
Log('DE-SERIALIZING Object');
Log('');
NewOb := TObj.Create('',0,false,0);
try
NewOb := ctx.AsType<TObj>(SO); // USE ctx -- EXCEPTION
finally
ctx.Free;
end;