我原本并不想单独发以下JCL的方法,可是想到很多人可能还是不知道的。另外,从我博客的回复上看,很多人也愿意去了解一下,特此贴出JCL中的代码。
//=== Interface information ==================================================function GetImplementorOfInterface(const I: IInterface): TObject;...{ TODO -cDOC : Original code by Hallvard Vassbotn }...{ TODO -cTesting : Check the implemetation for any further version of compiler }const AddByte = $04244483; // opcode for ADD DWORD PTR [ESP+4], Shortint AddLong = $04244481; // opcode for ADD DWORD PTR [ESP+4], Longinttype PAdjustSelfThunk = ^TAdjustSelfThunk; TAdjustSelfThunk = packed record case AddInstruction: Longint of AddByte: (AdjustmentByte: ShortInt); AddLong: (AdjustmentLong: Longint); end; PInterfaceMT = ^TInterfaceMT; TInterfaceMT = packed record QueryInterfaceThunk: PAdjustSelfThunk; end; TInterfaceRef = ^PInterfaceMT;var QueryInterfaceThunk: PAdjustSelfThunk;begin try Result := Pointer(I); if Assigned(Result) then begin QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfaceThunk; case QueryInterfaceThunk.AddInstruction of AddByte: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentByte); AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong); else Result := nil; end; end; except Result := nil; end;end;
注释:这段代码出自JCL代码中JclSysUtils单元中。
提示:读这段代码,要明白一个道理,在代码执行过程中,接口和对象指针的偏移是硬编码的在汇编中的。转换的过程,就是解析这段汇编的过程。
发表于 @ 2007年05月15日 21:43:00|评论(loading...)