Due to the length and style, the following hack has been turned into a The Delphi Magazine article. IMO, this is simply the best Delphi magazine for professional developers and I highly recommend a subscription. Don't forget to get the Collection CD to read all my old articles :-) (in addition lots of other great articles too, of course).
Read the magazine article (update: in the October issue) to get the complete hack, explanations, history, the clean alternative, sample code and .NET comparison. As a teaser, here is the actual hack code:
function GetImplementingObject(const I: IInterface): TObject;
const
AddByte = $04244483;
AddLong = $04244481;
type
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
Result := Pointer(I);
if Assigned(Result) then
try
QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfaceThunk;
case QueryInterfaceThunk.AddInstruction of
AddByte: Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentByte);
AddLong: Inc(PAnsiChar(Result), QueryInterfaceThunk.AdjustmentLong);
else
Result := nil;
end;
except
Result := nil;
end;
end;