Delphi Assembler / RTTI-gurus:我可以获取函数中隐含的Result
考虑这种典型的方法跟踪代码(简化说明):
type IMethodTracer = interface end; TMethodTracer = class(TInterfacedObject,IMethodTracer) private FName: String; FResultAddr: Pointer; FResultType: PTypeInfo; public constructor Create( const AName: String; const AResultAddr: Pointer = nil; const AResultType: PTypeInfo = nil); destructor Destroy; override; end; constructor TMethodTracer.Create( const AName: String; const AResultAddr: Pointer; const AResultType: PTypeInfo); begin inherited Create(); FName := AName; FResultAddr := AResultAddr; FResultType := AResultType; Writeln('Entering ' + FName); end; destructor TMethodTracer.Destroy; var lSuffix: String; lResVal: TValue; begin lSuffix := ''; if FResultAddr <> nil then begin //there's probably a more straight-forward to doing this,without involving TValue: TValue.Make(FResultAddr,FResultType,lResVal); lSuffix := ' - Result = ' + lResVal.AsString; end; Writeln('Leaving ' + FName + lSuffix); inherited Destroy; end; function TraceMethod( const AName: String; const AResultAddr: Pointer; const AResultType: PTypeInfo): IMethodTracer; begin Result := TMethodTracer.Create(AName,AResultAddr,AResultType); end; ////// function F1: String; begin TraceMethod('F1',@Result,TypeInfo(String)); Writeln('Doing some stuff...'); Result := 'Booyah!'; end; F1(); 这是按预期工作的.输出是:
我现在正在寻找一种方法来最小化调用TraceMethod()所需的参数数量,理想情况下允许我完全跳过与Result相关的参数.我自己没有使用汇编程序或堆栈布局的经验但是如果我没有弄错,从我见过的其他人所做的“魔法”判断,至少隐含的魔法Result-variable的内存地址应该可以以某种方式获得,不应该它?也许有人可以从那里得到它的类型信息吗? 当然,如果有可能甚至可以确定“周围”函数本身的名称,这将消除完全将参数传递给TraceMethod的需要…… 我正在使用Delphi XE2,因此可以使用所有最近引入的语言/框架功能. 在任何人提到它之前:我的实际代码已经使用CodeSite.EnterMethod / ExitMethod而不是Writeln调用.我也知道这个简化的例子不能处理复杂的类型,也不会执行任何错误处理. 解决方法
你最好的选择是真正传递@Result.如果不这样做,则无法保证Result甚至有地址.返回简单类型(如Integer和Boolean)的函数将结果放入EAX寄存器.如果没有理由让结果有地址,那么编译器就不会为它分配任何内存.使用@Result表达式强制编译器为其指定地址.
但是,仅仅知道地址不会得到返回类型.可能有一种方法可以通过RTTI发现它.这将涉及三个步骤: >从方法名称中提取类名.然后你可以get the RTTI for that type.这将要求方法名称包含类的明确名称(包括单位名称). 您可以改为遍历所有类的方法,而不是尝试匹配名称,搜索其 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |