Delphi如何确定哪个程序调用另一个程序?

时间:2010-09-02 23:16:16

标签: delphi

我如何确定谁给Showme程序打电话?

procedure Showme(str:string);
begin
  ShowMessage(str);
end;

procedure btnclick(sender:TObject);
begin
  Showme("test");
end;

procedure btn2click(sender:TObject);
begin
  Showme("test");
end;

编辑:混乱

Showme(654, '654'); // procedure name, string
Showme(654, '564');

4 个答案:

答案 0 :(得分:9)

一个程序没有内置的方法来知道哪个程序调用它。如果您真的需要知道,可以使用堆栈跟踪,但实际上只需要调试那种数据。对于实际执行,重要的是传递给例程的数据,而不是传递给它的地方。这是结构化编程的基本原则之一。如果两个不同的例程使用相同的数据调用相同的过程,则它们应该对它们进行相同的处理。

你究竟在做什么,你需要能够分辨出什么?可能有一种更简单的方法来实现它。

答案 1 :(得分:8)

为什么不传递一个不同的常量甚至是调用它作为Showme参数的过程的名称?可以分析堆栈以确定调用函数的名称,但它要复杂得多,您需要添加有关链接的信息(映射文件)。 Jedi的JCL有一些功能可以帮助你,但我会使用一个额外的参数。

答案 2 :(得分:2)

我假设您在调试器中运行应用程序,因此您可以在Showme过程中放置​​一个断点,当程序停止时,激活堆栈视图(查看/调试窗口/调用堆栈)。

它将向您显示谁调用它,实际上如果您双击任何堆栈条目,IDE将引导您进入调用的确切代码行(如果showme在每个调用例程中被调用多次)。 / p> 顺便说一句:我认为你必须更加努力地表达你的问题。

答案 3 :(得分:2)

TVirtualMethodInterceptor允许在实际方法之前和之后执行代码,并且有一个Method参数,其中包含方法名称:

示例代码:

type
  TFoo = class
  public
    procedure Bar; virtual;
  end;

procedure InterceptorBefore(Instance: TObject; Method: TRttiMethod;
  const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue);
begin
  ShowMessage('Before: ' + Instance.ClassName + '.' + Method.Name);
end;

procedure InterceptorAfter(Instance: TObject; Method: TRttiMethod;
  const Args: TArray<TValue>; var Result: TValue);
begin
  ShowMessage('After: ' + Instance.ClassName + '.' + Method.Name);
end;

{ TFoo }

procedure TFoo.Bar;
begin
  ShowMessage('TFoo.Bar');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  interceptor: TVirtualMethodInterceptor;
  foo: TFoo;
begin
  foo := TFoo.Create;

  interceptor := TVirtualMethodInterceptor.Create(TFoo);
  interceptor.Proxify(foo);
  interceptor.OnBefore := InterceptorBefore;
  interceptor.OnAfter := InterceptorAfter;

  foo.Bar;

end; 

请注意,这是Delphi XE中的新功能,因此我无法在系统上进行测试和验证。