json - 无法将 SuperObject JSON 反序列化为对象

标签 json delphi delphi-xe2 access-violation superobject

类型:

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;

测试代码:

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;

记录(数组)的第一部分工作得很好,而我想将 JSON 对象解析为新对象的 TObj 的第二部分在指定位置失败。我做错了什么?
顺便说一句,我不确定是否必须在 ctx.AsType 之前执行 NewOb := TObj.Create,但在这种情况下没有区别。

最佳答案

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;

关于json - 无法将 SuperObject JSON 反序列化为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17880390/

相关文章:

.net - 使用 .NET 创建一个 JSON 日期时间字符串

delphi-7 - Delphi:如何表达空的TDateTime?

delphi - 通过客户端-服务器断开连接管理 SQLConnection/Datasnap

javascript - 使用 jQuery 将 HTML 文本抓取为 JSON,但由于循环引用而无法进行字符串化

javascript - 如何将 json 字符串转换为特定格式?

delphi - 以编程方式从 filehoster 下载文件

delphi - Windows ETW : StartTrace failing with error 87 (ERROR_INVALID_PARAMETER)

delphi - TVirtualInterface 失败,接口(interface)包含 "function of object"属性

delphi - Delphi XE2中的RichEdit控件在某些样式下不会显示字体颜色

javascript - 格式化 JSON 数据以用于 Twitter Feed