2010-09-02 43 views
2

我如何確定誰稱爲Showme過程?Delphi如何確定哪個程序調用另一個程序?

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'); 
+0

你在用什麼來產生「混亂」。您發佈的代碼不會生成該輸出。如果你的兩個點擊事件說Showme(「654」)和Showme(「564」),那麼這將是有意義的(但讓你的問題毫無意義)。 – 2010-09-03 00:51:42

+0

困惑的程序是我對我的朋友的建議。但他不會使用它。 – 2010-09-03 00:53:15

+1

我比編輯的版本更理解原始問題(但那可能是我),但我不明白downvotes?! – 2010-09-03 07:12:29

回答

9

一個程序沒有內置的方法來知道哪個程序調用它。如果你真的需要知道,你可以使用堆棧跟蹤,但這類數據實際上只是用於調試。對於實際執行,重要的是傳遞給例程的數據,而不是來自哪裏。這是結構化編程的基本原則之一。如果兩個不同的例程使用相同的數據調用相同的過程,則它們應該相同。

你究竟在做什麼,你需要能夠分辨出差異?可能有更簡單的方法來完成它。

+0

我的朋友是一個老頭的程序員,他會做這個沒有額外的參數,我只是好奇,有沒有其他方式做到這一點。 – 2010-09-03 00:37:40

+0

不,就像梅森告訴你的,只有堆棧跟蹤,但不建議。你的朋友有一個錯誤的方法。告訴他只需使用一個額外的參數。他爲什麼拒絕?如果他擔心參數列表會很長,他可以使用記錄並將其作爲單個參數傳遞。 – Runner 2010-09-03 05:38:10

+1

@drorhan:不使用互聯網的老頭程序員Aha可以自問這個問題並解釋它。這樣的老頭程序員? ;-) – splash 2010-09-03 08:15:29

8

你爲什麼不通過調用它作爲SHOWME的參數的過程的不同的恆定,甚至叫什麼名字?可以分析堆棧以確定調用函數的名稱,但它要複雜得多,並且需要添加有關鏈接(映射文件)的信息。 Jedi的JCL有一些功能可以幫助你,但我會使用一個額外的參數。

+0

我的朋友問我這件事,我告訴他們你說什麼。但他只會發送一個參數,因爲混淆 – 2010-09-02 23:24:12

+3

實際上只有兩個答案:傳遞一個參數;或者查看調用堆棧。調用堆棧很複雜,用它來控制程序流並不是一個好主意(如果你從別的地方調用Showme()會發生什麼?)你可以看看你有的參數,但這也不可靠。 – 2010-09-03 00:53:56

2

我假設你正在調試器中運行應用程序,因此你可以在Showme過程中放置​​一個斷點,當程序停止時,激活堆棧視圖(view/debug windows/Call stack)。

它會告訴你是誰調用它,實際上如果你雙擊任何堆棧條目,IDE會將你引導到確實的調用代碼行(如果showme每次調用例程被調用多次)。

順便說一句:我認爲你必須做出更好的努力來表達你的問題。

2

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; 

注意這在Delphi XE是新,所以我無法在我的系統上進行測試和驗證。

相關問題