如何从外部查看器调试器可视化工具获取对象或其数据的引用?

时间:2011-11-13 01:16:00

标签: json delphi delphi-2010 delphi-xe debuggervisualizer

我正在尝试为TJSONObject或TJSONValue编写调试器可视化工具。我的大部分可视化工作都很好。我遇到的问题是获取对TJSONObject的引用,或至少引用TJSONObject的tostring()值。

根据我见过的样本,以及Jeremy North在http://edn.embarcadero.com/article/40268发表的精彩帖子,我应该从我的IOTADebuggerVisualizerExternalViewer实现的Show方法中得到我需要的东西。具体来说,来自Expression,TypeName和EvalResult字符串参数。

据我所知,Expression是被检查变量的名称(可视化),TypeName是变量的类名,EvalResult是变量的默认字符串表示。

对于一个简单的测试,我在我的TFrame后代放置了一个TMemo。从IOTADebuggerVisualizerExternalViewer.Show方法我调用我的TFrame的ShowJSONObject方法,我传递Expression,TypeName和EvalResult。相关代码显示在此处:

function TDebuggerJSONVisualizer.Show(const Expression, TypeName, EvalResult: string;
  SuggestedLeft, SuggestedTop: Integer): 
  IOTADebuggerVisualizerExternalViewerUpdater;
var
  AForm: TCustomForm;
  AFrame: TJSONViewerFrame;
  VisDockForm: INTACustomDockableForm;
begin
  VisDockForm := TJSONVisualizerForm.Create(Expression) as INTACustomDockableForm;
  AForm := (BorlandIDEServices as INTAServices).CreateDockableForm(VisDockForm);
  AForm.Left := SuggestedLeft;
  AForm.Top := SuggestedTop;
  (VisDockForm as IFrameFormHelper).SetForm(AForm);
  AFrame := (VisDockForm as IFrameFormHelper).GetFrame as TJSONViewerFrame;
  AFrame.ShowJSONObject(Expression, TypeName, EvalResult);
  Result := AFrame as IOTADebuggerVisualizerExternalViewerUpdater;
end;

{ TStringListViewerFrame }

procedure TJSONViewerFrame.ShowJSONObject(const Expression, TypeName,
  EvalResult: string);
begin
  Memo1.Lines.Add(Expression);
  Memo1.Lines.Add(TypeName);
  Memo1.Lines.Add(EvalResult);
end;

正如您所看到的,此时我只是尝试从ShowJSONObject方法中显示这三个参数的值。

这是我尝试使用可视化工具显示的简单TJSONObject:

var
 jo: TJSONObject;
begin
  jo := TJSONObject.Create;
  jo.AddPair('one', 'one');
  jo.AddPair('two', TJSONNumber.Create(1)); //a breakpoint here

结果如下:

A debugger visualizer under development

我希望EvalResult会返回TJSONObject的tostring表示,但它只返回uninformative(),这与你在局部变量窗口中默认看到的一样。

如何获取调用可视化器的TJSONObject的tostring表示或实际对象的句柄,以便我可以解构并显示其值?

1 个答案:

答案 0 :(得分:3)

您需要使用此过程评估您的表达式(包括ToString调用)(只是从我自己的可视化工具源复制,因此它可以使用一些未在此处声明的局部变量):

function TJSONViewerFrame.Evaluate(Expression: string): string;
var
  CurProcess: IOTAProcess;
  CurThread: IOTAThread;
  ResultStr: array[0..4095] of Char;
  CanModify: Boolean;
  ResultAddr, ResultSize, ResultVal: LongWord;
  EvalRes: TOTAEvaluateResult;
  DebugSvcs: IOTADebuggerServices;
begin
  begin
    Result := '';
    if Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
      CurProcess := DebugSvcs.CurrentProcess;
    if CurProcess <> nil then
    begin
      CurThread := CurProcess.CurrentThread;
      if CurThread <> nil then
      begin
        EvalRes := CurThread.Evaluate(Expression, @ResultStr, Length(ResultStr),
          CanModify, eseAll, '', ResultAddr, ResultSize, ResultVal, '', 0);
        case EvalRes of
          erOK: Result := ResultStr;
          erDeferred:
            begin
              FCompleted := False;
              FDeferredResult := '';
              FDeferredError := False;
              FNotifierIndex := CurThread.AddNotifier(Self);
              while not FCompleted do
                DebugSvcs.ProcessDebugEvents;
              CurThread.RemoveNotifier(FNotifierIndex);
              FNotifierIndex := -1;
              if not FDeferredError then
              begin
                if FDeferredResult <> '' then
                  Result := FDeferredResult
                else
                  Result := ResultStr;
              end;
            end;
          erBusy:
            begin
              DebugSvcs.ProcessDebugEvents;
              Result := Evaluate(Expression);
            end;
        end;
      end;
    end;
  end;
end;

现在您可以用以下内容替换Show函数:

AFrame.ShowJSONObject(Expression, TypeName, Evaluate(Expression + '.ToString'));