Home > How-To > Reference interfaces the right way in Borland Delphi

Created Oct 31, 2002
Last update Oct 31, 2002
Applies to Delphi 3 - 7
 
There are two possible ways of referencing objects which implements interfaces in Borland Delphi. Let's assume you have following interface:
IMyInterface = interface
  ['{B80F24F8-9FE5-4DF0-A5BF-A434271A2A50}']
  function Test: HResult; stdcall;
end;
 
And you have an object which implements it:
TMyObj = class(TInterfacedObject, IMyInterface)
public
  // IMyInterface
  function Test: HResult; stdcall;
end;
 
Here is the right way of using TMyObj:
procedure UseInterfaceRightWay;
var
  vMyInteface: IMyInterface; // interface
begin
  // working with TMyObj as IMyInterface
  vMyInteface := TMyObj.Create as IMyInterface;
  vMyInteface.Test;
end;
 
And here is the wrong way of using TMyObj:
procedure UseInterfaceWrongWay;
var
  vMyInteface: TMyObj; // object
begin
  // working with TMyObj as IMyInterface
  vMyInteface := TMyObj.Create;
  (vMyInteface as IMyInterface).Test;
  //vMyInteface.Free; // <- uncomment to see AV
end;
 
Why wrong way is wrong The first problem here is obvious: you can not destroy object using Free. As soon as you use object as interface the lifetime of the object is referenced counted and destructor will be called automatically as soon as object goes out of scope. Before (vMyInteface as IMyInterface).Test; call, vMyIntefac holds reference to object and after it holds reference to interface - surprise! The second problem is not as obvious, in fact you will ever face it only if you build a COM server which exposes interfaces to outside (non Delphi) clients. The best (in this case worst) client is VB.  Visual Basic COM clients tend to drop reference count to interfaces they acquire as soon as call completed. As result your Delphi COM server way experience all sorts of unexpected AVs with non with Delphi COM clients and especially with VB COM clients.        
 
Conclusion Life time of Delphi object and interface instances are managed very differently, reference count based for interfaces vs non reference counted based for objects.  Because of this different behavior I strongly recommend do not mix object and interface pointers. Inside Delphi applications this can lead to annoying code inconsistency, as for COM servers it can render them totally unusable.
 
Download Sample project is here
Hosted by www.Geocities.ws

1