Author: Tomas Rutkauskas
I'm trying to find a way to get the TObject reference from an IInterface object. I
know that if the interface loses the reference the object will destroy but I've got
a special need. The environment is based on interfaces but there is one component
that can't use interfaces. So to work around it I assign the interface to a local
variable, convert the interface to an object, call the component and when all is
done get rid of the interface variable. Is this the right approach or can anything
go wrong?
Answer:
1 2 function GetImplementingObject(const I: IInterface): TObject;
3 const4 AddByte = $04244483; {opcode for ADD DWORD PTR [ESP+4], Shortint}5 AddLong = $04244481; {opcode for ADD DWORD PTR [ESP+4], Longint}6 type7 PAdjustSelfThunk = ^TAdjustSelfThunk;
8 TAdjustSelfThunk = packedrecord9 case AddInstruction: longint of10 AddByte: (AdjustmentByte: shortint);
11 AddLong: (AdjustmentLong: longint);
12 end;
13 PInterfaceMT = ^TInterfaceMT;
14 TInterfaceMT = packedrecord15 QueryInterfaceThunk: PAdjustSelfThunk;
16 end;
17 TInterfaceRef = ^PInterfaceMT;
18 var19 QueryInterfaceThunk: PAdjustSelfThunk;
20 begin21 Result := Pointer(I);
22 if Assigned(Result) then23 try24 QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfaceThunk;
25 case QueryInterfaceThunk.AddInstruction of26 AddByte: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentByte);
27 AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong);
28 else29 Result := nil;
30 end;
31 except32 Result := nil;
33 end;
34 end;