代码之家  ›  专栏  ›  技术社区  ›  Orhan Cinar

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

  •  3
  • Orhan Cinar  · 技术社区  · 15 年前

    如何确定是谁调用了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 回复  |  直到 15 年前
        1
  •  9
  •   Mason Wheeler    15 年前

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

    你到底在做什么,你需要能够分辨出不同之处?可能有一种更简单的方法来完成它。

        2
  •  8
  •   Eduardo Mauro    15 年前

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

        3
  •  2
  •   jachguate    15 年前

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

    它将显示调用它的人,实际上,如果双击任何堆栈条目,IDE将引导您到达进行调用的确切代码行(如果每个调用例程多次调用showme)。

    顺便说一句:我认为你必须做出更好的努力来表达你的问题。

        4
  •  2
  •   mjn anonym    15 年前

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

    示例代码:

    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; 
    

    注意这在DelphiXE中是新的,所以我不能在系统上测试和验证它。