2010. március 1., hétfő

Get the TObject from an IInterface


Problem/Question/Abstract:

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:

function GetImplementingObject(const I: IInterface): TObject;
const
  AddByte = $04244483; {opcode for ADD DWORD PTR [ESP+4], Shortint}
  AddLong = $04244481; {opcode for ADD DWORD PTR [ESP+4], Longint}
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(PChar(Result), QueryInterfaceThunk.AdjustmentByte);
      AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong);
    else
      Result := nil;
    end;
  except
    Result := nil;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése