问题 如何强制链接器在调试期间包含我需要的函数?


我经常使用小方法来协助调试,这些方法在实际程序中没有使用。通常,我的大多数类都有一个AsString方法,我将其添加到手表中。我知道Delphi 2010有可视化工具,但我还在2007年。

考虑这个例子:

program Project1;

{$APPTYPE CONSOLE}

uses SysUtils;

type
  TMyClass = class
    F : integer;
    function AsString : string;
  end;

function TMyClass.AsString: string;
begin
  Result := 'Test: '+IntToStr(F);
end;

function SomeTest(aMC : TMyClass) : boolean;
begin
  //I want to be able to watch aMC.AsString while debugging this complex routine!
  Result := aMC.F > 100; 
end;

var
  X : TMyClass;

begin
  X := TMyClass.Create;
  try
    X.F := 100;
    if SomeTest(X)
      then writeln('OK')
      else writeln('Fail');
  finally
    X.Free;
  end;
  readln;
end.

如果我将X.AsString作为监视添加,我只是得到“要调用的函数,TMyClass.AsString,被链接器消除”。

如何强制链接器包含它?我通常的诀窍是 使用 程序中的某个方法,但是没有更优雅的方法吗?

回答: GJ提供了最好的方法。

initialization
  exit;
  TMyClass(nil).AsString;

end.

5174
2017-10-22 09:41


起源



答案:


sveinbringsli问:“你有单位功能的小费吗?”

Delphi编译器很聪明...... 所以你可以做点什么......

unit UnitA;

interface

{$DEFINE DEBUG}

function AsString: string;

implementation

function AsString: string;
begin
  Result := 'Test: ';
end;

{$IFDEF DEBUG}
initialization
  exit;
  AsString;
{$ENDIF}
end.

6
2017-10-22 11:32



+1。这就是我通常做的事情。将它放在初始化块中,这样它就不会被链接出来。 - Mason Wheeler
我正在与自己争论我应该接受哪个答案 - 这个或你的另一个答案与“已发布的技巧”。我选择了这个,因为它不会影响发布版本。 - Svein Bringsli
是的,如果你的函数需要一些参数如变量,只需在初始化部分写:“if @AsString = nil then;”而是将参数放入。 - GJ.
GJ,你的评论建议真的有效吗?我可能期望“表达式总是计算为false”提示,然后编译器可以删除表达式。 - Rob Kennedy
@Rob Kennedy:在我的测试用例中,uder D2007运行良好。我理解编译器首先插入函数代码然后测试地址。您还可以将Breakpoint设置为此行。核实。 - GJ.


答案:


sveinbringsli问:“你有单位功能的小费吗?”

Delphi编译器很聪明...... 所以你可以做点什么......

unit UnitA;

interface

{$DEFINE DEBUG}

function AsString: string;

implementation

function AsString: string;
begin
  Result := 'Test: ';
end;

{$IFDEF DEBUG}
initialization
  exit;
  AsString;
{$ENDIF}
end.

6
2017-10-22 11:32



+1。这就是我通常做的事情。将它放在初始化块中,这样它就不会被链接出来。 - Mason Wheeler
我正在与自己争论我应该接受哪个答案 - 这个或你的另一个答案与“已发布的技巧”。我选择了这个,因为它不会影响发布版本。 - Svein Bringsli
是的,如果你的函数需要一些参数如变量,只需在初始化部分写:“if @AsString = nil then;”而是将参数放入。 - GJ.
GJ,你的评论建议真的有效吗?我可能期望“表达式总是计算为false”提示,然后编译器可以删除表达式。 - Rob Kennedy
@Rob Kennedy:在我的测试用例中,uder D2007运行良好。我理解编译器首先插入函数代码然后测试地址。您还可以将Breakpoint设置为此行。核实。 - GJ.


你可以发布功能。

  TMyClass = class
    F : integer;
  published
    function AsString : string;
  end;

然后在'Watch Properties''允许函数调用'中打开


6
2017-10-22 10:20



大!我不知道发布的方法是这样的。你有单位功能的小费吗? - Svein Bringsli
您也可以将“已发布”发布为:{$ IFDEF DEBUG}已发布{$ ENDIF} - GJ.


也许它可以在一些初始化部分调用它们,由{IFDEF DEBUG}或{IFOPT D +}保护。


0
2017-10-22 10:31



是的,这可行,但我想找到一种方法 不 要求我在某处实际调用该函数。 - Svein Bringsli
当然那会很好。但至少它是一种解决方法,不会给版本带来负担。 (GJ发表的伎俩,BTW。:-)) - Uli Gerhardt