如何确定谁调用了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');
5条答案
按热度按时间yb3bgrhw1#
一个过程没有内置的方法来知道哪个过程调用了它。如果你真的需要知道,你可以使用堆栈跟踪,但是这类数据实际上只在调试时需要。对于实际执行,重要的是传递给例程的数据。而不是它来自哪里。这是结构化编程的基本原则之一。如果两个不同的例程使用相同的数据调用同一个过程,它应该对它们一视同仁。
你到底在做什么,你需要能够区分?可能有一个更简单的方法来完成它。
6qqygrtg2#
你为什么不传递一个不同的常量,甚至是调用它的过程的名称作为Showme的参数呢?为了确定调用函数的名称,可以分析堆栈,但这要复杂得多,你需要添加关于链接(Map文件)的信息。Jedi的JCL有一些函数可以帮助你,但我会使用一个额外的参数。
s8vozzvw3#
我假设您正在调试器中运行应用程序,因此您可以在Showme过程中放置一个断点,并在程序停止时激活堆栈视图(查看/调试窗口/调用堆栈)。
它将显示调用它的人,实际上,如果双击任何堆栈条目,IDE将引导您找到进行调用的确切代码行(以防每个调用例程多次调用showme)。
顺便说一句:我认为你必须更努力地表达你的问题。
svgewumm4#
TVirtualMethodInterceptor允许在实际方法之前和之后执行代码,并且有一个包含方法名称的Method参数:
示例代码:
注意这是Delphi XE中的新特性,所以我不能在我的系统上测试和验证它。
yvgpqqbh5#
好吧,如果你在modern Delphi上:
一旦你获得了指向函数调用指令的指针,你需要把地址转换成可读的字符串。默认情况下这是不可能的,因为编译后的可执行文件不包含函数名,只包含RAW地址(也有例外,比如RTTI,但这不是一般情况)。
但是,如果将调试信息附加到可执行文件,则可以读取它以将地址转换为名称。例如,如果您有EurekaLog:
然而:
1.只有在使用一些调试信息(以及corresponding debug info provider is enabled)进行编译时,它才能工作:
1.它不是一个常量。名字将被动态查找,所以它有一些运行时间开销。
P.S.请注意,你只应该为了日志记录/调试的目的这样做。你的应用逻辑不应该这样实现。你应该使用类,虚函数,RTTI,调度表,或脚本引擎-这取决于你想做什么。