快速识别当前程序调用位置的方法

nor*_*aul 2 delphi delphi-xe7

我需要找到一种方法来识别调用类中当前函数或过程的位置.如果结果是内存位置或单元和行号,则无关紧要,只是与调用来自的位置唯一的内容.

需要快速计算位置ID,因为它将用于确定缓存数据是否可用.

例如.

type
  TTestObject = class
  public
    procedure TestProc;
    procedure TestCall;
  end;  

...

procedure TTestObject.TestProc;
begin
  TestCall; // "Point A" - Displays "Point A"
  TestCall; // "Point B" - Displays "Point B"
end;

procedure TTestObject.TestCall;
begin
  ShowMessage(SomehowGetTheCallingLineLocation); // Displays "Point A" or "Point B" depending on which line above it is called from
end;

end.
Run Code Online (Sandbox Code Playgroud)

无论创建了多少TTestObject实例或它们驻留在内存中,调用TestProc时都会显示"Point A",然后显示"Point B".

该功能将用于生成SQL.目前,我将GUID传递给生成SQL的调用.如果已生成SQL,则此GUID用于从缓存中提取SQL.

  NewCommand(NewUpdateCriteria('{C43D3B79-9E73-4A4B-9E29-0553542AD0B2}').
    SetValue('AFIELD', AValue).
  Table
    ('ATABLE').
  Where
    (NewSQLComparitor
    ('ID', EqualTo, AID)));
Run Code Online (Sandbox Code Playgroud)

查询调用位置需要很快,否则它会通过缓存SQL来消除我们应该看到的速度改进.

该组件最终可能成为开源,因此我无法使用任何商业第三方组件.我还想避免依赖JEDI这样的开源库.

Dav*_*nan 5

根据您更新的问题,您只需要能够识别一个呼叫来自与另一个呼叫不同的地方.在这种情况下,您可以使用返回地址来标识呼叫者.并且可以通过调用未记录的内部函数来获得返回地址System.ReturnAddress.

这个程序:

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

procedure Foo;
begin
  Writeln(IntToHex(NativeInt(ReturnAddress), 8));
end;

begin
  Foo;
  Foo;
  Foo;
  Foo;
end.
Run Code Online (Sandbox Code Playgroud)

在我的机器上生成此输出:

0041B491
0041B496
0041B49B
0041B4A0

  • +1,因为这直接有效地回答了这个问题,因为我已经学到了新的东西.也就是说,这对OP的问题来说是一个非常可怕的解决方案 - 考虑到这些要求,这种代码混淆似乎完全没有道理.将信息输入方法的常规方法是将其作为参数传递.我认为没有充分理由说这不适用于此.除非有人编写异常处理程序或其他类似的东西,否则基于方法返回地址的条件分支就像是一场噩梦... (2认同)