Thursday, July 29, 2004

Hack #7: Interface to Object [in The Delphi Magazine]

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;

15 comments:

Anonymous said...

It doesn't look good in a RSS aggregator, such as SharpReader. Appears black on blue. Very very hard to read.

Chee Wee. ;o)

Hallvard Vassbotn said...

So? Sue me...! :-P

Seriously, that does sound like a bug in your RSS reader?

I like the classic Delphi colors ;).

Anonymous said...

> I like the classic Delphi colors ;).
Actually they're the original Turbo Pascal (and TC) colors (says an old-enough-to-have-actually-been-a-programmer-before-Delphi-existed programmer ) :-)

Matthijs Hebly, The Netherlands

John E said...

First, I must add a disclaimer to the fact that I did not read The Delphi Magazine article, but I agree with you that it has the best content for the price.

The hack is certainly 'cool' and will be a hack solution in some cases... but in this is not a good thing to use because the whole objective of interfaces is to hide the implimentation from the user of the interface. If you misused this call, would it introduce implementation dependancies to the user of the interface? This would violate the Dependency Inversion Principle of OO design.
Ref www.objectmentor.com

Hallvard Vassbotn said...

John,

Indeed - that's what I say in the TDM article as well ;). And I show how to solve it the clean way. This is a last-resort hack when there so no other way to perform a task.

Fluffy said...

>Actually they're the original Turbo >Pascal (and TC) colors (says an >old-enough-to-have-actually-been-a-programmer-before-Delphi-existed >programmer ) :-)

I still use them in delphi, cause I'm so used to the TP colors. *chuckle*

Fernando Madruga said...

I prefer black as my background color in the text editor: less straining on my eyes for prolonged coding sessions! :)

Similar, but not exactly equal, to the Twilight color scheme: I start with that scheme then make a couple changes...

But, for display in a webpage, this TP classic style has a bit more oomph...

Fernando Madruga said...

Now I understand the reference to "The Delphi Magazine" which I though was dead: it is dead, it's just DelphiFeeds picking up your old articles because you're changing your site! :)

Ceniza said...

Note to those wanting to use this hack in newer versions of Delphi (2009+): You must change the two occurrences of PChar to PAnsiChar, otherwise you will get twice the increment (PChar is 2 bytes now by default).

Robson Braga said...

Man, that was exactly what I needed! Thanx a lot!

Arnaud said...

Note also that for later versions of Delphi (since Delphi 2005 AFAIR), you have the "as" operator. See my own version in http://blog.synopse.info/post/2012/06/13/Retrieve-the-object-instance-from-an-interface

m2studio said...
This comment has been removed by the author.
m2studio said...

I tried this code but it cannot was compiled in my machine.

Incompatible types: 'TObject' and '_Pointer' << compiled error in the line below:
Result := Pointer(I);

How do I fix it ?

Hallvard Vassbotn said...

You probably have strict pointer types turned on in compiler options - you can probably compile the code by changing it to:

Result := TObject(Pointer(I));

m2studio said...

Thank you for your quick answer.



Copyright © 2004-2007 by Hallvard Vassbotn